vue实现动态权限路由
实现动态权限路由的核心思路
动态权限路由的核心是根据用户权限动态生成可访问的路由表,通常分为以下步骤:
- 用户登录后获取权限数据(角色或权限标识)
- 过滤异步路由表,保留有权限的路由
- 将过滤后的路由动态添加到路由器实例
基础路由配置
创建基础路由表,包含无需权限的公共路由:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const publicRoutes = [
{
path: '/login',
component: () => import('@/views/login.vue')
},
{
path: '/404',
component: () => import('@/views/404.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes: publicRoutes
})
export default router
异步路由表配置
创建需要权限控制的路由表:
// router/asyncRoutes.js
export const asyncRoutes = [
{
path: '/dashboard',
component: () => import('@/views/dashboard.vue'),
meta: { requiresAuth: true, roles: ['admin'] }
},
{
path: '/user',
component: () => import('@/views/user.vue'),
meta: { requiresAuth: true, roles: ['admin', 'editor'] }
}
]
权限验证逻辑
实现路由过滤函数,根据用户权限筛选可用路由:
// utils/permission.js
export function filterRoutes(routes, roles) {
return routes.filter(route => {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
}
return true
})
}
动态添加路由
在用户登录后或应用初始化时动态添加路由:
// 通常在登录后或应用初始化时调用
import { asyncRoutes } from './router/asyncRoutes'
import { filterRoutes } from './utils/permission'
function addRoutes(roles) {
const accessedRoutes = filterRoutes(asyncRoutes, roles)
accessedRoutes.forEach(route => {
router.addRoute(route)
})
// 添加404通配路由
router.addRoute({ path: '/:pathMatch(.*)', redirect: '/404' })
}
路由守卫配置
设置全局前置守卫进行权限校验:
// router/index.js
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.getters.userRoles) {
next('/login')
} else {
const hasPermission = to.matched.some(record => {
return record.meta.roles?.some(role =>
store.getters.userRoles.includes(role)
)
})
hasPermission ? next() : next('/403')
}
} else {
next()
}
})
菜单生成方案
通常需要将过滤后的路由转换为菜单数据:
function generateMenus(routes) {
return routes.map(route => {
const menu = {
path: route.path,
title: route.meta?.title || '',
icon: route.meta?.icon || ''
}
if (route.children) {
menu.children = generateMenus(route.children)
}
return menu
})
}
状态管理集成
建议将权限相关数据存储在Vuex或Pinia中:
// store/modules/user.js
export default {
state: () => ({
roles: []
}),
mutations: {
SET_ROLES(state, roles) {
state.roles = roles
}
},
actions: {
async fetchUserRoles({ commit }) {
const roles = await api.getUserRoles()
commit('SET_ROLES', roles)
return roles
}
}
}
完整实现流程
- 用户登录成功后获取权限数据
- 根据权限数据过滤异步路由表
- 使用router.addRoute动态添加过滤后的路由
- 将路由数据转换为菜单数据供前端展示
- 设置路由守卫进行实时权限校验
注意事项
- 动态添加的路由不会持久化,刷新页面后需要重新添加
- 404路由应当最后添加,避免被提前匹配
- 路由元信息(meta)是存储权限数据的好地方
- 后端返回的路由数据可能需要转换为Vue Router所需格式







