From 19348408d3d8ab67847fddfb8f9605db45045da2 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Wed, 7 May 2025 13:23:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=90=9C=E7=B4=A2=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=94=AE=E7=9B=98=E9=80=89=E6=8B=A9&=E6=82=AC?= =?UTF-8?q?=E6=B5=AE=E4=B8=BB=E9=A2=98=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/svg/enter.svg | 1 + src/components/HeaderSearch/index.vue | 42 ++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/assets/icons/svg/enter.svg diff --git a/src/assets/icons/svg/enter.svg b/src/assets/icons/svg/enter.svg new file mode 100644 index 0000000..f7cabf2 --- /dev/null +++ b/src/assets/icons/svg/enter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue index b57fe69..d325951 100644 --- a/src/components/HeaderSearch/index.vue +++ b/src/components/HeaderSearch/index.vue @@ -16,12 +16,15 @@ prefix-icon="Search" placeholder="菜单搜索,支持标题、URL模糊查询" clearable + @keyup.enter="selectActiveResult" + @keydown.up.prevent="navigateResult('up')" + @keydown.down.prevent="navigateResult('down')" >
-
+
@@ -33,6 +36,7 @@ {{ item.path }}
+
@@ -44,15 +48,18 @@ import Fuse from 'fuse.js' import { getNormalPath } from '@/utils/ruoyi' import { isHttp } from '@/utils/validate' +import useSettingsStore from '@/store/modules/settings' import usePermissionStore from '@/store/modules/permission' const search = ref('') const options = ref([]) const searchPool = ref([]) +const activeIndex = ref(-1) const show = ref(false) const fuse = ref(undefined) const headerSearchSelectRef = ref(null) const router = useRouter() +const theme = computed(() => useSettingsStore().theme) const routes = computed(() => usePermissionStore().defaultRoutes) function click() { @@ -68,6 +75,7 @@ function close() { search.value = '' options.value = [] show.value = false + activeIndex.value = -1 } function change(val) { @@ -149,6 +157,7 @@ function generateRoutes(routes, basePath = '', prefixTitle = []) { } function querySearch(query) { + activeIndex.value = -1 if (query !== '') { options.value = fuse.value.search(query).map((item) => item.item) ?? searchPool.value } else { @@ -156,6 +165,28 @@ function querySearch(query) { } } +function activeStyle(index) { + if (index !== activeIndex.value) return {} + return { + "background-color": theme.value, + "color": "#fff" + } +} + +function navigateResult(direction) { + if (direction === "up") { + activeIndex.value = activeIndex.value <= 0 ? options.value.length - 1 : activeIndex.value - 1 + } else if (direction === "down") { + activeIndex.value = activeIndex.value >= options.value.length - 1 ? 0 : activeIndex.value + 1 + } +} + +function selectActiveResult() { + if (options.value.length > 0 && activeIndex.value >= 0) { + change(options.value[activeIndex.value]) + } +} + onMounted(() => { searchPool.value = generateRoutes(routes.value) }) @@ -174,13 +205,15 @@ watch(searchPool, (list) => { } } -.result-wrap { +.result-wrap { height: 280px; - margin: 10px 0; + margin: 6px 0; .search-item { display: flex; height: 48px; + align-items: center; + padding-right: 10px; .left { width: 60px; @@ -189,16 +222,17 @@ watch(searchPool, (list) => { .menu-icon { width: 18px; height: 18px; - margin-top: 5px; } } .search-info { padding-left: 5px; + margin-top: 10px; width: 100%; display: flex; flex-direction: column; justify-content: flex-start; + flex: 1; .menu-title, .menu-path {