Vue3 动态路由权限配置详解
1. 角色路由映射配置
javascript
// 定义角色可访问的路由映射
export const roleRoutes = {
// 超级管理员权限配置
'平台管理员': 'all', // 可访问所有路由
'法人': 'all',
// 公司管理员权限配置 - 使用排除法
'公司管理员': {
exclude: [
// 不可访问的路由列表
]
},
// 评委权限配置 - 使用白名单
'评委': [
// 基础功能路由
// 评委专属功能路
],
// 招标人权限配置 - 使用白名单
'招标人': [
// 基础功能路由
// 招标业务相关路由
// 公告与归档相关路由
// 客户管理相关路由
],
// 投标人权限配置 - 使用白名单
'投标人': [
// 基础功能路由
// 投标业务相关路
// 客户管理相关路由
],
}
// 路由过滤函数
export function filterRoutes(routes, role) {
// 处理超级管理员权限
if (role === '平台管理员' || roleRoutes[role] === 'all') {
return routes // 直接返回所有路由
}
// 使用扩展运算符创建routes数组的浅拷贝,用于后续路由过滤
// 这样可以避免修改原始routes数组
const stack = [...routes]
const result = []
// 使用栈进行路由过滤
while (stack.length) {
// 从栈中弹出当前路由
const current = stack.pop()
// 处理带有子路由的情况
if (current.children?.length) {
// 过滤子路由
// 1. 需要单独处理子路由的权限,因为父路由可能有权限但子路由没有权限
// 2. 使用filter过滤出有权限的子路由
const filteredChildren = current.children.filter(child =>
// 检查路由是否在允许列表中且不在排除列表中
roleRoutes[role]?.includes(child.path) &&
!(roleRoutes[role]?.exclude?.includes(child.path))
)
// 如果过滤后还有子路由,则保留父路由
// 1. 只有当子路由至少有一个有权限时才保留父路由
// 2. 这样可以避免出现空的父级菜单
if (filteredChildren.length) {
current.children = filteredChildren
result.push(current)
}
} else if (
// 处理没有子路由的情况
// 既在白名单中,又不在排除列表中
roleRoutes[role]?.includes(current. path) &&
!(roleRoutes[role]?.exclude?.includes (current.path))
) {
result.push(current)
}
}
return result
}
2. 配置说明
2.1 角色类型
平台管理员:系统最高权限,可访问所有路由 法人:与平台管理员相同权限 公司管理员:使用排除法,指定不可访问的路由 评委:使用白名单,明确指定可访问的路由 招标人:使用白名单,可访问招标相关功能 投标人:使用白名单,可访问投标相关功能
2.2 权限控制方式
. 全部权限('all'):直接赋予所有路由访问权限 . 排除法(exclude):指定不可访问的路由列表 . 白名单:明确列出可访问的路由路径
2.3 路由过滤逻辑
. 优先处理超级管理员权限 . 使用栈结构处理多级路由 . 分别处理有子路由和无子路由的情况 . 同时支持白名单和排除列表的权限判断
3. 使用注意事项
. 路由配置需要与实际路由表匹配 . 注意路由路径的大小写敏感性 . 子路由的权限继承关系处理 . 动态路由的性能优化考虑
使用示例:
javascript
// 假设有这样的路由配置
const routes = [
{
path: '/admin',
children: [
{ path: '/admin/users' },
{ path: '/admin/settings' }
]
}
]
// 对于平台管理员
const adminRoutes = filterRoutes(routes, '平台管理员')
// 返回完整的路由配置
// 对于普通投标人
const bidderRoutes = filterRoutes(routes, '投标人')
// 只返回投标人有权限访问的路由