From b2639184261f59279c98611f775f3fe821449e15 Mon Sep 17 00:00:00 2001
From: LiuHao <liuhaoai545@gmail>
Date: 星期三, 19 四月 2023 23:25:34 +0800
Subject: [PATCH] update searchMenu style
---
src/layout/components/topBar/search.vue | 158 +++++++++++++++++++++++++++++++++++++++
.eslintrc.js | 3
src/layout/components/Navbar.vue | 16 +++
src/components/HeaderSearch/index.vue | 8 +-
4 files changed, 178 insertions(+), 7 deletions(-)
diff --git a/.eslintrc.js b/.eslintrc.js
index 2b2e0d0..b6b10a6 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -29,7 +29,8 @@
// 鍏抽棴绌虹被鍨嬫鏌� {}
extendDefaults: true,
types: {
- '{}': false
+ '{}': false,
+ 'Function': false
}
}
]
diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue
index 60ebb9d..f0ab1c9 100644
--- a/src/components/HeaderSearch/index.vue
+++ b/src/components/HeaderSearch/index.vue
@@ -17,7 +17,7 @@
</div>
</template>
-<script setup lang="ts">
+<script setup lang="ts" name="HeaderSearch">
import Fuse from 'fuse.js'
import { getNormalPath } from '@/utils/ruoyi'
import { isHttp } from '@/utils/validate'
@@ -123,9 +123,9 @@
searchPool.value = generateRoutes(routes.value);
})
-watchEffect(() => {
- searchPool.value = generateRoutes(routes.value)
-})
+// watchEffect(() => {
+// searchPool.value = generateRoutes(routes.value)
+// })
watch(show, (value) => {
if (value) {
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 156011f..8b9624e 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -20,8 +20,13 @@
<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
</el-select>
- <header-search id="header-search" class="right-menu-item" />
-
+ <!-- <header-search id="header-search" class="right-menu-item" /> -->
+ <search-menu ref="searchMenuRef" />
+ <el-tooltip content="鎼滅储" effect="dark" placement="bottom">
+ <div class="right-menu-item hover-effect" @click="openSearchMenu">
+ <svg-icon class-name="search-icon" icon-class="search" />
+ </div>
+ </el-tooltip>
<el-tooltip content="Github" effect="dark" placement="bottom">
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
</el-tooltip>
@@ -68,6 +73,7 @@
</template>
<script setup lang="ts">
+import SearchMenu from './topBar/search.vue'
import useAppStore from '@/store/modules/app'
import useUserStore from '@/store/modules/user'
import useSettingsStore from '@/store/modules/settings'
@@ -89,6 +95,12 @@
const dynamic = ref(false);
// 绉熸埛寮�鍏�
const tenantEnabled = ref(true);
+// 鎼滅储鑿滃崟
+const searchMenuRef = ref<InstanceType<typeof SearchMenu>>();
+
+const openSearchMenu = () => {
+ searchMenuRef.value?.openSearch()
+}
// 鍔ㄦ�佸垏鎹�
const dynamicTenantEvent = async (tenantId: string) => {
diff --git a/src/layout/components/topBar/search.vue b/src/layout/components/topBar/search.vue
new file mode 100644
index 0000000..3b707e4
--- /dev/null
+++ b/src/layout/components/topBar/search.vue
@@ -0,0 +1,158 @@
+<template>
+ <div class="layout-search-dialog">
+ <el-dialog v-model="state.isShowSearch" destroy-on-close :show-close="false">
+ <template #footer>
+ <el-autocomplete
+ v-model="state.menuQuery"
+ :fetch-suggestions="menuSearch"
+ placeholder="鎼滅储"
+ ref="layoutMenuAutocompleteRef"
+ @select="onHandleSelect"
+ :fit-input-width="true"
+ >
+ <template #prefix>
+ <svg-icon class-name="search-icon" icon-class="search" />
+ </template>
+ <template #default="{ item }">
+ <div>
+ <svg-icon :icon-class="item.icon" class="mr5" />
+ {{ item.title }}
+ </div>
+ </template>
+ </el-autocomplete>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup lang="ts" name="layoutBreadcrumbSearch">
+import { getNormalPath } from '@/utils/ruoyi';
+import { isHttp } from '@/utils/validate';
+import usePermissionStore from '@/store/modules/permission';
+import { RouteOption } from 'vue-router';
+type Router = Array<{
+ path: string;
+ icon: string;
+ title: string[];
+}>
+type SearchState<T = any> = {
+ isShowSearch: boolean;
+ menuQuery: string;
+ menuList: T[];
+};
+// 瀹氫箟鍙橀噺鍐呭
+const layoutMenuAutocompleteRef = ref();
+const router = useRouter();
+const routes = computed(() => usePermissionStore().routes);
+const state = reactive<SearchState>({
+ isShowSearch: false,
+ menuQuery: '',
+ menuList: [],
+});
+
+// 鎼滅储寮圭獥鎵撳紑
+const openSearch = () => {
+ state.menuQuery = '';
+ state.isShowSearch = true;
+ state.menuList = generateRoutes(routes.value);
+ nextTick(() => {
+ setTimeout(() => {
+ layoutMenuAutocompleteRef.value.focus();
+ });
+ });
+};
+// 鎼滅储寮圭獥鍏抽棴
+const closeSearch = () => {
+ state.isShowSearch = false;
+};
+// 鑿滃崟鎼滅储鏁版嵁杩囨护
+const menuSearch = (queryString: string, cb: Function) => {
+ let options = state.menuList.filter((item) => {
+ return item.title.indexOf(queryString) > -1;
+ });
+ cb(options);
+};
+
+// Filter out the routes that can be displayed in the sidebar
+// And generate the internationalized title
+const generateRoutes = (routes: RouteOption[], basePath = '', prefixTitle: string[] = []) => {
+ let res: Router = []
+ routes.forEach(r => {
+ // skip hidden router
+ if (!r.hidden) {
+ const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path;
+ const data: any = {
+ path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path,
+ icon: r.meta?.icon,
+ title: [...prefixTitle]
+ }
+ if (r.meta && r.meta.title) {
+ data.title = [...data.title, r.meta.title];
+ if (r.redirect !== 'noRedirect') {
+ // only push the routes with title
+ // special case: need to exclude parent router without redirect
+ res.push(data);
+ }
+ }
+ // recursive child routes
+ if (r.children) {
+ const tempRoutes = generateRoutes(r.children, data.path, data.title);
+ if (tempRoutes.length >= 1) {
+ res = [...res, ...tempRoutes];
+ }
+ }
+ }
+ })
+ res.forEach((item: any) => {
+ if (item.title instanceof Array) {
+ item.title = item.title.join('/');
+ }
+ });
+ return res;
+}
+// 褰撳墠鑿滃崟閫変腑鏃�
+const onHandleSelect = (val: any) => {
+ const paths = val.path;
+ if (isHttp(paths)) {
+ // http(s):// 璺緞鏂扮獥鍙f墦寮�
+ const pindex = paths.indexOf("http");
+ window.open(paths.substring(pindex, paths.length), "_blank");
+ } else {
+ router.push(paths)
+ }
+ state.menuQuery = ''
+ closeSearch();
+
+};
+
+// 鏆撮湶鍙橀噺
+defineExpose({
+ openSearch
+});
+</script>
+
+<style scoped lang="scss">
+.layout-search-dialog {
+ position: relative;
+ :deep(.el-dialog) {
+ .el-dialog__header,
+ .el-dialog__body {
+ display: none;
+ }
+ .el-dialog__footer {
+ width: 100%;
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ top: -53vh;
+ }
+ }
+ :deep(.el-autocomplete) {
+ width: 560px;
+ position: absolute;
+ top: 150px;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+}
+</style>
--
Gitblit v1.9.3