修复:解决web-admin左侧菜单重复显示问题
- 创建独立的菜单配置文件 menu.ts - 修改Layout.vue使用静态菜单配置而不是动态路由生成 - 移除子路由中重复的图标配置 - 优化菜单渲染逻辑,避免重复显示 修复内容: 1. 菜单配置独立化:避免从路由动态生成导致的重复 2. 简化菜单结构:只显示必要的顶级菜单项 3. 图标去重:移除子路由中重复的图标定义
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
export interface MenuItem {
|
||||||
|
path: string
|
||||||
|
title: string
|
||||||
|
icon?: string
|
||||||
|
children?: MenuItem[]
|
||||||
|
hidden?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const menuConfig: MenuItem[] = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
title: '仪表盘',
|
||||||
|
icon: 'DataLine'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/admin',
|
||||||
|
title: '管理员管理',
|
||||||
|
icon: 'User'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/user',
|
||||||
|
title: '用户管理',
|
||||||
|
icon: 'UserFilled'
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -11,30 +11,32 @@
|
|||||||
:unique-opened="true"
|
:unique-opened="true"
|
||||||
router
|
router
|
||||||
>
|
>
|
||||||
<template v-for="route in menuRoutes" :key="route.path">
|
<template v-for="item in menuRoutes" :key="item.path">
|
||||||
<el-sub-menu v-if="route.children && route.children.length > 1" :index="route.path">
|
<!-- 如果有子菜单,显示为子菜单 -->
|
||||||
|
<el-sub-menu v-if="item.children && item.children.length > 0" :index="item.path">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon v-if="route.meta?.icon">
|
<el-icon v-if="item.icon">
|
||||||
<component :is="route.meta.icon" />
|
<component :is="item.icon" />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>{{ route.meta?.title }}</span>
|
<span>{{ item.title }}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
v-for="child in route.children"
|
v-for="child in item.children"
|
||||||
:key="child.path"
|
:key="child.path"
|
||||||
:index="route.path + '/' + child.path"
|
:index="child.path"
|
||||||
>
|
>
|
||||||
<el-icon v-if="child.meta?.icon">
|
<el-icon v-if="child.icon">
|
||||||
<component :is="child.meta.icon" />
|
<component :is="child.icon" />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>{{ child.meta?.title }}</span>
|
<span>{{ child.title }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
<el-menu-item v-else :index="route.redirect || route.path">
|
<!-- 没有子菜单,直接显示为菜单项 -->
|
||||||
<el-icon v-if="route.meta?.icon">
|
<el-menu-item v-else :index="item.path">
|
||||||
<component :is="route.meta.icon" />
|
<el-icon v-if="item.icon">
|
||||||
|
<component :is="item.icon" />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>{{ route.meta?.title }}</span>
|
<span>{{ item.title }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
@@ -78,6 +80,7 @@ import { ref, computed, onMounted } from 'vue'
|
|||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useAdminStore } from '@/stores/admin'
|
import { useAdminStore } from '@/stores/admin'
|
||||||
import { Fold, Expand } from '@element-plus/icons-vue'
|
import { Fold, Expand } from '@element-plus/icons-vue'
|
||||||
|
import { menuConfig } from '@/config/menu'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -89,9 +92,7 @@ const adminInfo = computed(() => adminStore.adminInfo)
|
|||||||
const activeMenu = computed(() => route.path)
|
const activeMenu = computed(() => route.path)
|
||||||
|
|
||||||
const menuRoutes = computed(() => {
|
const menuRoutes = computed(() => {
|
||||||
return router.getRoutes().filter(r =>
|
return menuConfig.filter(item => !item.hidden)
|
||||||
r.path === '/' || (r.path.startsWith('/') && !r.meta?.hidden && r.component?.name !== 'Layout')
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleCollapse = () => {
|
const toggleCollapse = () => {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
path: 'list',
|
path: 'list',
|
||||||
name: 'AdminList',
|
name: 'AdminList',
|
||||||
component: () => import('@/views/admin/AdminList.vue'),
|
component: () => import('@/views/admin/AdminList.vue'),
|
||||||
meta: { title: '管理员列表', icon: 'User' }
|
meta: { title: '管理员列表' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -45,7 +45,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
path: 'list',
|
path: 'list',
|
||||||
name: 'UserList',
|
name: 'UserList',
|
||||||
component: () => import('@/views/user/UserList.vue'),
|
component: () => import('@/views/user/UserList.vue'),
|
||||||
meta: { title: '用户列表', icon: 'UserFilled' }
|
meta: { title: '用户列表' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user