style: 全局菜单搜索仅过滤菜单名称

This commit is contained in:
TsMask
2025-09-17 15:10:08 +08:00
parent 749e880aa7
commit 4a5008f1b5

View File

@@ -2,11 +2,7 @@
<!-- 搜索按钮 -->
<a-tooltip placement="bottom">
<template #title>{{ t('common.search') }}</template>
<a-button
type="text"
style="color: inherit"
@click="fnClickSearch"
>
<a-button type="text" style="color: inherit" @click="fnClickSearch">
<template #icon>
<SearchOutlined />
</template>
@@ -38,11 +34,13 @@
<SearchOutlined style="color: #bfbfbf" />
</template>
</a-input>
<div class="search-results">
<div v-if="filteredMenus.length === 0" class="no-results">
<a-empty
:description="searchKeyword ? t('common.noData') : t('common.searchTip')"
<a-empty
:description="
searchKeyword ? t('common.noData') : t('common.searchTip')
"
:image="false"
/>
</div>
@@ -55,15 +53,15 @@
>
<div class="menu-icon">
<!-- 处理自定义图标字体 -->
<IconFont
v-if="menu.icon && menu.icon.startsWith('icon-')"
<IconFont
v-if="menu.icon && menu.icon.startsWith('icon-')"
:type="menu.icon"
class="icon"
/>
<!-- 处理Ant Design图标组件 -->
<component
:is="menu.icon"
v-else-if="menu.icon && !menu.icon.startsWith('icon-')"
<component
:is="menu.icon"
v-else-if="menu.icon && !menu.icon.startsWith('icon-')"
class="icon"
/>
<!-- 默认图标 -->
@@ -83,10 +81,7 @@
</template>
<script setup lang="ts">
import {
getMenuData,
clearMenuItem
} from 'antdv-pro-layout';
import { getMenuData, clearMenuItem } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import IconFont from '@/components/IconFont/index.vue';
import { ref, computed, nextTick } from 'vue';
@@ -127,7 +122,7 @@ const searchableMenus = computed(() => {
} else {
rootRoute.children = children;
}
// 根据用户角色过滤
if (!userStore.roles.includes('tenant')) {
rootRoute.children = rootRoute.children.filter(
@@ -164,26 +159,30 @@ const searchableMenus = computed(() => {
try {
const title = t(route.meta.title);
// 避免重复添加已存在的路由
const exists = menus.find(m => m.routeName === route.name || m.path === fullPath);
const exists = menus.find(
m => m.routeName === route.name || m.path === fullPath
);
if (!exists) {
menus.push({
title: title,
path: fullPath,
icon: route.meta.icon,
key: route.name || fullPath,
routeName: route.name
routeName: route.name,
});
}
} catch (error) {
// 如果翻译失败,使用原始标题
const exists = menus.find(m => m.routeName === route.name || m.path === fullPath);
const exists = menus.find(
m => m.routeName === route.name || m.path === fullPath
);
if (!exists) {
menus.push({
title: route.meta.title,
path: fullPath,
icon: route.meta.icon,
key: route.name || fullPath,
routeName: route.name
routeName: route.name,
});
}
}
@@ -198,7 +197,7 @@ const searchableMenus = computed(() => {
// 使用和菜单面板相同的数据源
const menuRoutes = getMenuDataForSearch();
if (menuRoutes && menuRoutes.length > 0) {
getRouteItems(menuRoutes);
}
@@ -211,18 +210,22 @@ const filteredMenus = computed(() => {
if (!searchKeyword.value.trim()) {
return searchableMenus.value.slice(0, 10); // 默认显示前10个
}
return searchableMenus.value.filter(menu =>
menu.title.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
menu.path.toLowerCase().includes(searchKeyword.value.toLowerCase())
).slice(0, 10);
// return searchableMenus.value.filter(menu =>
// menu.title.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
// menu.path.toLowerCase().includes(searchKeyword.value.toLowerCase())
// ).slice(0, 10);
const value = searchKeyword.value.toLowerCase();
return searchableMenus.value
.filter(menu => menu.title.toLowerCase().includes(value))
.slice(0, 10);
});
/**打开搜索弹窗 */
function fnClickSearch() {
searchModalOpen.value = true;
searchKeyword.value = '';
nextTick(() => {
searchInputRef.value?.focus();
});
@@ -268,12 +271,12 @@ function fnHandleKeydown(e: KeyboardEvent) {
.search-results {
max-height: 400px;
overflow-y: auto;
.no-results {
text-align: center;
padding: 40px 0;
}
.menu-list {
.menu-item {
display: flex;
@@ -283,15 +286,15 @@ function fnHandleKeydown(e: KeyboardEvent) {
cursor: pointer;
transition: all 0.2s ease;
margin-bottom: 4px;
&:hover {
background-color: #f5f5f5;
.menu-action {
opacity: 1;
}
}
.menu-icon {
margin-right: 12px;
display: flex;
@@ -301,17 +304,17 @@ function fnHandleKeydown(e: KeyboardEvent) {
height: 32px;
background-color: #f0f2f5;
border-radius: 6px;
.icon {
font-size: 16px;
color: #666;
}
}
.menu-info {
flex: 1;
min-width: 0;
.menu-title {
font-size: 14px;
font-weight: 500;
@@ -321,7 +324,7 @@ function fnHandleKeydown(e: KeyboardEvent) {
text-overflow: ellipsis;
white-space: nowrap;
}
.menu-path {
font-size: 12px;
color: #8c8c8c;
@@ -330,7 +333,7 @@ function fnHandleKeydown(e: KeyboardEvent) {
white-space: nowrap;
}
}
.menu-action {
opacity: 0;
transition: opacity 0.2s ease;
@@ -343,7 +346,7 @@ function fnHandleKeydown(e: KeyboardEvent) {
}
// 暗黑主题支持
[data-theme="dark"] {
[data-theme='dark'] {
.search-modal-content {
.search-results {
.menu-list {
@@ -351,20 +354,20 @@ function fnHandleKeydown(e: KeyboardEvent) {
&:hover {
background-color: #303030;
}
.menu-icon {
background-color: #262626;
.icon {
color: #bfbfbf;
}
}
.menu-info {
.menu-title {
color: #f0f0f0;
}
.menu-path {
color: #8c8c8c;
}