此框架中路由权限使用了两种方法,主要介绍第二种方法。
- 从路由表构建路由(前端对比后端权限字段过滤静态路由表)
即:前端配置好全部的路由表,然后根据权限来与后端获取到的进行对比,最终展示对比后的数据。
- 从后端获取路由表结构体,并构建前端路由
从后端获取到菜单列表,此菜单列表为当前角色权限的菜单列表,然后对此列表进行处理,处理为路由所需格式的路由数组即可。
我个人用的是第二种的方法,以下主要介绍第二种方法。
1. 在store/user.ts中,找到 GENERATE_ROUTES_DYNAMIC 方法中调用的方法:generatorDynamicRouter(),此方法在在router/router-guards/router-guards.ts中。
2. router/router-guards/router-guards.ts中,通过方法getCurrentUserNav(),获取到个人信息中的菜单,将菜单列表传generator()方法中,此方法将菜单列表处理成路由所需格式的路由数组。
export const generator = (
routeMap: RouteItem[],
parentId: string | number,
routeItem?: RouteRecordRaw | MenuDataItem,
) => {
return routeMap
.filter(item => item.pid === parentId)
.map(item => {
const { hideInMenu, hideChildrenInMenu, target, authority } = item.meta || {};
const currentRouter: MenuDataItem = {
// 如果路由设置了 path,则作为默认 path,否则 路由地址 动态拼接生成如 /dashboard/workplace
path: item.path || `${(routeItem && routeItem.path) || ''}/${item.name}`,
// 路由名称,建议唯一
name: item.name || `${item.id}`,
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
meta: {
title:item.title,
icon:item.icon||undefined,
hideInMenu,
hideChildrenInMenu,
target: target,
authority: authority,
},
// 该路由对应页面的 组件 (动态加载 @/views/ 下面的路径文件)
component:
item.component && defineRouteComponentKeys.includes(item.path)
? defineRouteComponents[item.path]
: () => import(/* @vite-ignore */ `../views${item.path}/index.vue`)
};
// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
if (!currentRouter.path.startsWith('http')) {
currentRouter.path = currentRouter.path.replace('//', '/');
}
// 重定向
item.redirect && (currentRouter.redirect = item.redirect);
// 子菜单,递归处理
currentRouter.children = generator(routeMap, item.nid, currentRouter);
if (currentRouter.children === undefined || currentRouter.children.length <= 0) {
delete currentRouter.children;
}
return currentRouter;
})
.filter(item => item);
};
即:以下格式:
3. 最后将路由动态添加到路由表: