From c13c622eac5551c6f099f148feb5256711ca34de Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期二, 11 七月 2023 21:03:01 +0800 Subject: [PATCH] !25 部分优化以及新增功能 Merge pull request !25 from ahaos/tspr --- src/layout/components/topBar/search.vue | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 158 insertions(+), 0 deletions(-) diff --git a/src/layout/components/topBar/search.vue b/src/layout/components/topBar/search.vue new file mode 100644 index 0000000..9dee360 --- /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