vue实现动态权限路由
实现动态权限路由的核心思路
动态权限路由的核心是根据用户权限动态生成可访问的路由表。通常分为以下步骤:
- 初始化基础路由:定义无需权限的公共路由(如登录页、404页)。
- 获取用户权限:从接口或本地存储获取用户权限标识(如角色、权限列表)。
- 过滤动态路由:根据权限筛选出符合条件的路由配置。
- 添加路由到实例:通过
router.addRoutes(Vue Router 3)或router.addRoute(Vue Router 4)注入路由。
基础路由与动态路由分离
// 基础路由(所有用户可见)
const constantRoutes = [
{ path: '/login', component: Login },
{ path: '/404', component: NotFound }
]
// 动态路由(需权限控制)
const asyncRoutes = [
{ path: '/admin', component: Admin, meta: { roles: ['admin'] } },
{ path: '/user', component: User, meta: { roles: ['user', 'admin'] } }
]
权限验证逻辑
通过路由的meta.roles字段与用户角色进行匹配:

function hasPermission(roles, route) {
if (route.meta?.roles) {
return roles.some(role => route.meta.roles.includes(role))
}
return true // 无meta.roles视为公开路由
}
路由过滤实现
递归过滤异步路由表:

function filterRoutes(routes, roles) {
return routes.filter(route => {
if (hasPermission(roles, route)) {
if (route.children) {
route.children = filterRoutes(route.children, roles)
}
return true
}
return false
})
}
完整流程示例
- 用户登录后获取角色:
// 模拟获取用户角色
const roles = ['admin'] // 实际从接口获取
- 生成可访问路由:
const accessedRoutes = filterRoutes(asyncRoutes, roles)
- 动态添加路由:
router.addRoutes(accessedRoutes)
accessedRoutes.forEach(route => router.addRoute(route))
- 保存路由状态(可选):
store.commit('user/SET_ROUTES', accessedRoutes) // 存入Vuex/Pinia
404路由处理
动态路由添加后需在最后追加404路由:
// Vue Router 3
router.addRoutes([{ path: '*', redirect: '/404', hidden: true }])
// Vue Router 4
router.addRoute({ path: '/:pathMatch(.*)*', redirect: '/404' })
路由守卫控制
在全局前置守卫中实现权限控制:
router.beforeEach(async (to, from, next) => {
if (hasToken()) {
if (to.path === '/login') {
next('/')
} else {
if (!hasRoles()) {
try {
const roles = await getRoles() // 获取用户角色
const accessedRoutes = filterRoutes(asyncRoutes, roles)
router.addRoutes(accessedRoutes)
next({ ...to, replace: true }) // 确保addRoutes生效
} catch (error) {
next(`/login?redirect=${to.path}`)
}
} else {
next()
}
}
} else {
if (whiteList.includes(to.path)) {
next()
} else {
next(`/login?redirect=${to.path}`)
}
}
})
注意事项
- 路由配置:动态路由的
component需使用() => import()懒加载。 - 菜单生成:前端菜单通常基于过滤后的路由表渲染。
- 按钮权限:可与
v-permission指令结合实现细粒度控制。 - 路由重置:退出登录时需要重置路由实例(Vue Router 4可通过
router.removeRoute())。
扩展优化
- 路由持久化:将过滤后的路由存入sessionStorage避免每次刷新重新拉取。
- 后端控制:更安全的做法是由后端返回完整路由结构,前端直接注册。
- 路由缓存:结合
<keep-alive>对需要缓存的路由进行标记。





