From bf2d45416f209c057dc45999bf04cc7387dcc827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=BC=A0=E9=BE=99?= Date: Sat, 23 Apr 2022 22:34:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8D=95=E4=B8=AA=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E6=97=B6=E6=9B=BF=E6=8D=A2=E7=88=B6=E8=8F=9C=E5=8D=95=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/AppIcons/index.js | 1 + src/layout/components/sidebar/SideMenu.vue | 63 +++++++++++----------- src/router/routes/index.js | 55 +++++++++++-------- src/router/routes/modules/example.js | 3 ++ src/store/modules/permission.js | 3 ++ 5 files changed, 70 insertions(+), 55 deletions(-) diff --git a/src/components/AppIcons/index.js b/src/components/AppIcons/index.js index 51a2608..fb37360 100644 --- a/src/components/AppIcons/index.js +++ b/src/components/AppIcons/index.js @@ -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 IconExpandLeft } from '~icons/mdi/arrow-expand-left' 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' diff --git a/src/layout/components/sidebar/SideMenu.vue b/src/layout/components/sidebar/SideMenu.vue index 0268aee..9b938fe 100644 --- a/src/layout/components/sidebar/SideMenu.vue +++ b/src/layout/components/sidebar/SideMenu.vue @@ -15,7 +15,7 @@ import { useRouter } from 'vue-router' import { computed } from 'vue' import { usePermissionStore } from '@/store/modules/permission' -import { IconCircle, IconMenu } from '@/components/AppIcons' +import { IconCircle } from '@/components/AppIcons' import { isExternal } from '@/utils/is' import { useAppStore } from '@/store/modules/app' @@ -27,7 +27,7 @@ const appStore = useAppStore() const { currentRoute } = router const menuOptions = computed(() => { - return generateOptions(permissionStore.routes, '') + return permissionStore.menus.map((item) => getMenuItem(item)) }) function resolvePath(basePath, path) { @@ -41,40 +41,37 @@ function resolvePath(basePath, path) { ) } -function isSingleRoute(route) { - let isSingle = true - 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] - } +function getMenuItem(route, basePath = '') { + let menuItem = { + label: (route.meta && route.meta.title) || route.name, + key: route.name, + path: resolvePath(basePath, route.path), + icon: route.meta?.icon ? renderIcon(route.meta?.icon, { size: 16 }) : renderIcon(IconCircle, { size: 8 }), } - 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, - key: route.name, - path: resolvePath(basePath, route.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 { - curOption.icon = (route.meta?.icon && renderIcon(route.meta?.icon)) || renderIcon(IconCircle, { size: 8 }) - } - options.push(curOption) + 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 }), } - }) - return options + if (singleRoute.children && singleRoute.children.length) { + menuItem.children = singleRoute.children.map((item) => getMenuItem(item, menuItem.path)) + } + } else { + menuItem.children = route.children.map((item) => getMenuItem(item, menuItem.path)) + } + + return menuItem } function handleMenuSelect(key, item) { diff --git a/src/router/routes/index.js b/src/router/routes/index.js index c429257..3073a81 100644 --- a/src/router/routes/index.js +++ b/src/router/routes/index.js @@ -1,7 +1,16 @@ import Layout from '@/layout/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 = [ { @@ -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', path: '/test', @@ -62,6 +93,7 @@ export const basicRoutes = [ redirect: '/test/unocss', meta: { title: '基础功能测试', + icon: IconMenu, }, 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', path: '/external-link', diff --git a/src/router/routes/modules/example.js b/src/router/routes/modules/example.js index b0af10e..e18b3d0 100644 --- a/src/router/routes/modules/example.js +++ b/src/router/routes/modules/example.js @@ -1,4 +1,6 @@ +import { IconMenuTable } from '@/components/AppIcons' import Layout from '@/layout/index.vue' +import { markRaw } from 'vue' export default [ { @@ -19,6 +21,7 @@ export default [ meta: { title: '表格', role: ['admin'], + icon: markRaw(IconMenuTable), }, children: [ { diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index d23c1f7..1188260 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -38,6 +38,9 @@ export const usePermissionStore = defineStore('permission', { routes() { return basicRoutes.concat(this.accessRoutes) }, + menus() { + return this.routes.filter((route) => route.name && !route.isHidden) + }, }, actions: { generateRoutes(role = []) {