Skip to content

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, '投标人')
// 只返回投标人有权限访问的路由