前提
你的菜單是根據路由動態生成的,具體可以參考這篇博客對el-menu組件進行遞歸封裝(根據路由配置動態生成)
描述
首先將路由分為常量路由
constantRoute
(所有用戶都有的路由)和異步路由asyncRoute
(需要動態加載的前端路由)
每次進入系統時根據不同的用戶向后端發送請求獲取該用戶的路由權限信息,一般是個數組。
所使用的API
1.動態添加路由api
router.addRoute(parentName: string, route: RouteConfig): () => void
實現的例子
路由配置信息(大概掃一眼就行,就是v-router的配置)
export const constantRoute = [{path: '/login',component: () => import('@/views/login/index.vue'),name: 'login',meta: {title: '登錄',hidden: true,},},{path: '/',component: () => import('@/views/layout/index.vue'),name: 'layout',meta: {title: '',hidden: false,icon: '',},redirect: '/home',children: [{path: '/home',component: () => import('@/views/home/index.vue'),name: 'home',meta: {title: '首頁',hidden: false,icon: 'HomeFilled',},},],},{path: '/screen',component: () => import('@/views/screen/index.vue'),name: 'Screen',meta: {title: '數據大屏',hidden: false,icon: 'DataBoard',},},{path: '/404',component: () => import('@/views/404/index.vue'),name: '404',meta: {title: 'Not Found',hidden: true,},},{path: '/:pathMatch(.*)*',redirect: '404',name: 'Any',meta: {title: 'Not Found',hidden: true,},},
]export const asyncRoute = [{path: '/acl',component: () => import('@/views/layout/index.vue'),name: 'Acl',meta: {title: '權限管理',hidden: false,icon: 'Lock',},redirect: '/acl/user',children: [{path: '/acl/user',component: () => import('@/views/acl/user/index.vue'),name: 'User',meta: {title: '用戶管理',hidden: false,icon: 'User',},},{path: '/acl/role',component: () => import('@/views/acl/role/index.vue'),name: 'Role',meta: {title: '角色管理',hidden: false,icon: 'Avatar',},},{path: '/acl/permission',component: () => import('@/views/acl/permission/index.vue'),name: 'Permission',meta: {title: '菜單管理',hidden: false,icon: 'List',},},],},{path: '/product',component: () => import('@/views/layout/index.vue'),name: 'Product',meta: {title: '商品管理',hidden: false,icon: 'Goods',},redirect: '/product/trademark',children: [{path: '/product/trademark',component: () => import('@/views/product/trademark/index.vue'),name: 'Trademark',meta: {title: '品牌管理',icon: 'ShoppingCart',hidden: false,},},{path: '/product/attr',component: () => import('@/views/product/attr/index.vue'),name: 'Attr',meta: {title: '屬性管理',icon: 'Management',hidden: false,},},{path: '/product/spu',component: () => import('@/views/product/spu/index.vue'),name: 'Spu',meta: {title: 'Spu',icon: 'SetUp',hidden: false,},},{path: '/product/sku',component: () => import('@/views/product/sku/index.vue'),name: 'Sku',meta: {title: 'Sku',icon: 'ScaleToOriginal',hidden: false,},},],},
]
// 計算異步路由信息
function generateRoutes(asyncRoutes: any, filterArr: string[]) {return asyncRoutes.filter((item: any) => {if (filterArr.includes(item.name)) {if (item.children && item.children.length > 0) {item.children = generateRoutes(item.children, filterArr)}return true}})
}
// filterArr 權限信息
const filterArr = ['Acl', 'User', 'Role', 'Product', 'Trademark']
const asyncRoutes = generateRoutes(// 一定要使用深拷貝 用lodash的cloneDeep,不要用JSON的那個cloneDeep(asyncRoute),filterArr,
)
// this.routes主要是側邊導航欄要的信息 可有可無
this.routes = [...constantRoute, ...asyncRoutes,...anyRoute];
// 動態注冊路由
[...asyncRoutes,...anyRoute].forEach((item:any) => {router.addRoute(item)
});
注意:如果出現Vue 路由定義警告Component “default“ in record with path “/“ is a Promise
這個問題可以嘗試在路由前置守衛中加入判斷使用next({ ...to })
不懂得可以參考這篇