Vue3 动态路由与路由守卫实现 
1. 项目背景 
在中后台管理系统中,不同角色的用户需要看到不同的菜单和访问不同的页面。为了实现这个需求,我们需要通过动态路由和路由守卫来控制用户的访问权限。
2. 技术实现 
2.1 核心依赖 
- Vue Router
 - Pinia(状态管理)
 - NProgress(进度条)
 
2.2 实现思路 
- 设置路由白名单
 - 配置全局路由守卫
 - 根据用户角色动态判断路由权限
 - 处理路由跳转逻辑
 
2.3 具体实现 
2.3.1 路由守卫配置 
javascript
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { useLoginStore } from '@/store/modules/userlogin'
import { roleRoutes } from './permission'
const whiteList = ['/login']
export function setupRouterGuard(router) {
  // 配置进度条
  NProgress.configure({ showSpinner: false })
  // 路由前置守卫
  router.beforeEach(async (to, from, next) => {
    const store = useLoginStore()
    
    NProgress.start()
    
    const token = store.token
    const message = store.message
    
    if (message === '登录凭证失效' || !token) {
      // 如果要去的页面在白名单中,则直接放行
      if (whiteList.includes(to.path)) {
        next()
      } else {
        // 否则,重定向到登录页面,并携带要去的页面路径,登录成功后,会重定向到要去的页面
        next({
          path: '/login',
          query: { redirect: to.fullPath }
        })
      }
    } else if (token) {
      // 获取用户角色并解析
      const userRoles = JSON.parse(localStorage.getItem('userInfo')).split(',')
      // 检查用户是否有权限访问要去的页面
      const hasPermission = checkRoutePermission(to.path, userRoles)
      // 如果没有权限,则阻止访问
      if (!hasPermission) {
        NProgress.done()
        return next(false)
      }
      
      if (to.path === '/login') {
        // 如果有重定向参数就跳转到保存的路由,否则跳转到默认页面
        const redirect = to.query.redirect
        next(redirect || '/DefaultContent')
      } else if (to.path === '/') {
        // 根据角色决定默认页面
        const defaultPath = '/DefaultContent'
        next(defaultPath)
      } else {
        next()
      }
    } else {
      if (whiteList.includes(to.path)) {
        next()
      } else {
        next('/login')
      }
    }
    NProgress.done()   // 结束进度条
  })
  // 路由后置守卫
  router.afterEach(() => {
    NProgress.done()   // 结束进度条
  })
  // 路由错误处理
  router.onError((error) => {
    console.error('路由错误:', error)
    NProgress.done()   // 结束进度条
  })
}2.3.2 权限检查函数 
javascript
// 修改权限检查函数以支持多角色
function checkRoutePermission(path, roles) {
  // 如果用户有任何一个角色具有权限,就允许访问
  return roles.some(role => {
    if (role === '平台管理员' || roleRoutes[role] === 'all') {
      return true
    }
    return roleRoutes[role]?.includes(path)
  })
}3. 核心功能解析 
3.1 路由守卫功能 
- 进度条处理:使用 NProgress 在路由切换时显示进度条
 - 登录状态检查:检查 token 和登录状态
 - 权限控制:根据用户角色控制页面访问权限
 - 路由重定向:处理登录后的重定向逻辑
 
3.2 权限控制逻辑 
- 多角色支持:用户可以拥有多个角色
 - 白名单机制:某些路由无需登录即可访问
 - 平台管理员特权:平台管理员拥有所有路由访问权限
 - 角色路由映射:通过 roleRoutes 配置不同角色可访问的路由
 
4. 重点 
4.1 技术要点 
如何实现动态路由?
- 通过路由守卫 beforeEach 控制路由访问
 - 根据用户角色动态判断权限
 - 使用路由元信息存储权限信息
 
权限控制的实现方式?
- 基于角色的访问控制(RBAC)
 - 使用路由守卫进行权限判断
 - 支持多角色权限叠加
 
登录状态管理?
- 使用 Pinia 管理登录状态
 - token 存储和验证
 - 登录失效处理
 
4.2 性能优化 
- 路由懒加载
 - 权限判断缓存
 - 进度条优化
 
4.3 安全考虑 
- 前端权限控制只是辅助,后端也需要进行权限验证
 - token 安全存储
 - 敏感信息加密处理
 
5. 项目优化建议 
- 可以考虑使用路由元信息(meta)存储权限信息
 - 实现路由权限的缓存机制
 - 添加更细粒度的权限控制
 - 优化路由切换的性能
 
6. 总结 
动态路由和权限控制是中后台项目的重要组成部分,通过合理的路由守卫配置和权限判断逻辑,可以实现灵活的权限控制系统。在实际项目中,需要根据具体需求进行定制和优化。