feat: 单个菜单时替换父菜单处理

This commit is contained in:
张传龙 2022-04-23 22:34:12 +08:00
parent cf1b83d3f1
commit bf2d45416f
5 changed files with 70 additions and 55 deletions

View File

@ -13,5 +13,6 @@ export { default as IconClose } from '~icons/mdi/close'
export { default as IconExpand } from '~icons/mdi/arrow-expand-horizontal' export { default as IconExpand } from '~icons/mdi/arrow-expand-horizontal'
export { default as IconExpandLeft } from '~icons/mdi/arrow-expand-left' export { default as IconExpandLeft } from '~icons/mdi/arrow-expand-left'
export { default as IconExpandRight } from '~icons/mdi/arrow-expand-right' export { default as IconExpandRight } from '~icons/mdi/arrow-expand-right'
export { default as IconMenuTable } from '~icons/mdi/table'
export { default as IconLogo } from './IconLogo.vue' export { default as IconLogo } from './IconLogo.vue'

View File

@ -15,7 +15,7 @@ import { useRouter } from 'vue-router'
import { computed } from 'vue' import { computed } from 'vue'
import { usePermissionStore } from '@/store/modules/permission' import { usePermissionStore } from '@/store/modules/permission'
import { IconCircle, IconMenu } from '@/components/AppIcons' import { IconCircle } from '@/components/AppIcons'
import { isExternal } from '@/utils/is' import { isExternal } from '@/utils/is'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
@ -27,7 +27,7 @@ const appStore = useAppStore()
const { currentRoute } = router const { currentRoute } = router
const menuOptions = computed(() => { const menuOptions = computed(() => {
return generateOptions(permissionStore.routes, '') return permissionStore.menus.map((item) => getMenuItem(item))
}) })
function resolvePath(basePath, path) { function resolvePath(basePath, path) {
@ -41,40 +41,37 @@ function resolvePath(basePath, path) {
) )
} }
function isSingleRoute(route) { function getMenuItem(route, basePath = '') {
let isSingle = true let menuItem = {
let curRoute = route
while (curRoute.children && curRoute.children.length) {
if (curRoute.children.length > 1) {
isSingle = false
break
}
if (curRoute.children.length === 1) {
curRoute = curRoute.children[0]
}
}
return isSingle
}
function generateOptions(routes, basePath) {
let options = []
routes.forEach((route) => {
if (route.name && !route.isHidden) {
let curOption = {
label: (route.meta && route.meta.title) || route.name, label: (route.meta && route.meta.title) || route.name,
key: route.name, key: route.name,
path: resolvePath(basePath, route.path), path: resolvePath(basePath, route.path),
icon: route.meta?.icon ? renderIcon(route.meta?.icon, { size: 16 }) : renderIcon(IconCircle, { size: 8 }),
}
if (!route.children || !route.children.length) {
return menuItem
}
if (route.children && route.children.length === 1) {
//
const singleRoute = route.children[0]
menuItem = {
label: singleRoute.meta?.title || singleRoute.name,
key: singleRoute.name,
path: resolvePath(menuItem.path, singleRoute.path),
icon: singleRoute.meta?.icon
? renderIcon(singleRoute.meta?.icon, { size: 16 })
: renderIcon(IconCircle, { size: 8 }),
}
if (singleRoute.children && singleRoute.children.length) {
menuItem.children = singleRoute.children.map((item) => getMenuItem(item, menuItem.path))
} }
if (route.children && route.children.length) {
curOption.icon = renderIcon(route.meta?.icon || IconMenu, { size: 16 })
curOption.children = generateOptions(route.children, resolvePath(basePath, route.path))
} else { } else {
curOption.icon = (route.meta?.icon && renderIcon(route.meta?.icon)) || renderIcon(IconCircle, { size: 8 }) menuItem.children = route.children.map((item) => getMenuItem(item, menuItem.path))
} }
options.push(curOption)
} return menuItem
})
return options
} }
function handleMenuSelect(key, item) { function handleMenuSelect(key, item) {

View File

@ -1,7 +1,16 @@
import Layout from '@/layout/index.vue' import Layout from '@/layout/index.vue'
import Home from '@/views/dashboard/index.vue' import Home from '@/views/dashboard/index.vue'
import { IconAlert, IconChart, IconGitee, IconGithub, IconHome, IconLink, IconVue } from '@/components/AppIcons' import {
IconAlert,
IconChart,
IconGitee,
IconGithub,
IconHome,
IconLink,
IconMenu,
IconVue,
} from '@/components/AppIcons'
export const basicRoutes = [ export const basicRoutes = [
{ {
@ -55,6 +64,28 @@ export const basicRoutes = [
], ],
}, },
{
name: 'ErrorPage',
path: '/error-page',
component: Layout,
redirect: '/error-page/404',
meta: {
title: '错误页',
icon: IconAlert,
},
children: [
{
name: 'ERROR-404',
path: '404',
component: () => import('@/views/error-page/404.vue'),
meta: {
title: '404',
icon: IconAlert,
},
},
],
},
{ {
name: 'Test', name: 'Test',
path: '/test', path: '/test',
@ -62,6 +93,7 @@ export const basicRoutes = [
redirect: '/test/unocss', redirect: '/test/unocss',
meta: { meta: {
title: '基础功能测试', title: '基础功能测试',
icon: IconMenu,
}, },
children: [ children: [
{ {
@ -100,27 +132,6 @@ export const basicRoutes = [
], ],
}, },
{
name: 'ErrorPage',
path: '/error-page',
component: Layout,
redirect: '/error-page/404',
meta: {
title: '错误页',
icon: IconAlert,
},
children: [
{
name: 'ERROR-404',
path: '404',
component: () => import('@/views/error-page/404.vue'),
meta: {
title: '404',
},
},
],
},
{ {
name: 'ExternalLink', name: 'ExternalLink',
path: '/external-link', path: '/external-link',

View File

@ -1,4 +1,6 @@
import { IconMenuTable } from '@/components/AppIcons'
import Layout from '@/layout/index.vue' import Layout from '@/layout/index.vue'
import { markRaw } from 'vue'
export default [ export default [
{ {
@ -19,6 +21,7 @@ export default [
meta: { meta: {
title: '表格', title: '表格',
role: ['admin'], role: ['admin'],
icon: markRaw(IconMenuTable),
}, },
children: [ children: [
{ {

View File

@ -38,6 +38,9 @@ export const usePermissionStore = defineStore('permission', {
routes() { routes() {
return basicRoutes.concat(this.accessRoutes) return basicRoutes.concat(this.accessRoutes)
}, },
menus() {
return this.routes.filter((route) => route.name && !route.isHidden)
},
}, },
actions: { actions: {
generateRoutes(role = []) { generateRoutes(role = []) {