diff --git a/.vscode/settings.json b/.vscode/settings.json index 3036ebf1..5b3aa477 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,7 @@ "source.fixAll.eslint": true }, "[vue]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "Vue.volar" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" diff --git a/src/App.vue b/src/App.vue index 75edd24f..f75478cd 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,6 +3,7 @@ import { isDark } from '@/utils/is' import { useAppStore } from '@/store/modules/app' import { useDesign } from '@/hooks/web/useDesign' import { CACHE_KEY, useCache } from '@/hooks/web/useCache' +import routerSearch from '@/components/RouterSearch/index.vue' const { getPrefixCls } = useDesign() const prefixCls = getPrefixCls('app') @@ -24,10 +25,12 @@ setDefaultTheme() <template> <ConfigGlobal :size="currentSize"> <RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" /> + <routerSearch /> </ConfigGlobal> </template> <style lang="scss"> $prefix-cls: #{$namespace}-app; + .size { width: 100%; height: 100%; diff --git a/src/components/RouterSearch/index.vue b/src/components/RouterSearch/index.vue new file mode 100644 index 00000000..d44ce267 --- /dev/null +++ b/src/components/RouterSearch/index.vue @@ -0,0 +1,76 @@ +<template> + <ElDialog v-model="showSearch" :show-close="false" title="菜单搜索"> + <el-select + filterable + :reserve-keyword="false" + remote + placeholder="请输入菜单内容" + :remote-method="remoteMethod" + style="width: 100%" + @change="handleChange" + > + <el-option + v-for="item in options" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </ElDialog> +</template> + +<script setup lang="ts"> +const router = useRouter() // 路由对象 +const showSearch = ref(false) // 是否显示弹框 +const value: Ref = ref('') // 用户输入的值 + +const routers = router.getRoutes() // 路由对象 +const options = computed(() => { + // 提示选项 + if (!value.value) { + return [] + } + const list = routers.filter((item: any) => { + if (item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) { + return true + } + }) + return list.map((item) => { + return { + label: `${item.meta.title}${item.path}`, + value: item.path + } + }) +}) + +function remoteMethod(data) { + // 这里可以执行相应的操作(例如打开搜索框等) + value.value = data +} + +function handleChange(path) { + router.push({ path }) +} + +onMounted(() => { + window.addEventListener('keydown', listenKey) +}) + +onUnmounted(() => { + window.removeEventListener('keydown', listenKey) +}) + +// 监听 ctrl + k +function listenKey(event) { + if ((event.ctrlKey || event.metaKey) && event.key === 'k') { + showSearch.value = !showSearch.value + // 这里可以执行相应的操作(例如打开搜索框等) + } +} + +defineExpose({ + openSearch: () => { + showSearch.value = true + } +}) +</script>