addroutes和vue实现权限
使用 addRoutes 和 Vue 实现权限控制
在 Vue 项目中,动态路由(addRoutes)是实现权限控制的常见方式。通过根据用户权限动态加载路由,可以确保用户只能访问其权限范围内的页面。
核心思路
-
路由分为静态路由和动态路由
- 静态路由:所有用户均可访问的路由(如登录页、404页)。
- 动态路由:根据用户权限动态加载的路由(如后台管理页面)。
-
权限验证流程
- 用户登录后,后端返回用户权限标识(如角色或权限列表)。
- 前端根据权限标识筛选可访问的路由,并通过
addRoutes动态添加到路由实例。
实现步骤
1. 定义静态路由和动态路由
在 router/index.js 中拆分路由:
// 静态路由(所有用户均可访问)
export const constantRoutes = [
{ path: '/login', component: () => import('@/views/Login.vue') },
{ path: '/404', component: () => import('@/views/404.vue') }
];
// 动态路由(需权限控制)
export const asyncRoutes = [
{
path: '/admin',
component: () => import('@/views/Admin.vue'),
meta: { roles: ['admin'] } // 需要 admin 角色
},
{
path: '/user',
component: () => import('@/views/User.vue'),
meta: { roles: ['user', 'admin'] } // 需要 user 或 admin 角色
}
];
2. 创建路由实例并初始化
import Vue from 'vue';
import Router from 'vue-router';
import { constantRoutes } from './router';
Vue.use(Router);
const createRouter = () => new Router({
routes: constantRoutes // 初始仅加载静态路由
});
const router = createRouter();
export default router;
3. 权限验证与动态加载路由
在用户登录后,根据权限动态加载路由:
import { asyncRoutes } from '@/router';
// 模拟后端返回的用户权限
const userRole = 'admin'; // 实际从接口获取
// 过滤动态路由
function filterRoutes(routes, roles) {
return routes.filter(route => {
if (route.meta?.roles) {
return route.meta.roles.includes(roles);
}
return true;
});
}
// 动态添加路由
const accessedRoutes = filterRoutes(asyncRoutes, userRole);
router.addRoutes(accessedRoutes);
// 添加 404 路由捕获未匹配路径
router.addRoutes([{ path: '*', redirect: '/404' }]);
4. 路由守卫控制访问权限
在全局路由守卫中校验权限:
router.beforeEach((to, from, next) => {
const hasToken = localStorage.getItem('token');
// 未登录且访问非登录页,跳转到登录页
if (!hasToken && to.path !== '/login') {
next('/login');
}
// 已登录且访问登录页,跳转到首页
else if (hasToken && to.path === '/login') {
next('/');
}
// 校验动态路由权限
else if (to.meta?.roles) {
const userRole = localStorage.getItem('role');
if (to.meta.roles.includes(userRole)) {
next();
} else {
next('/403'); // 无权限页面
}
}
// 其他情况放行
else {
next();
}
});
注意事项
-
路由重置问题
addRoutes方法不会覆盖原有路由,重复调用可能导致路由重复。解决方案是在动态加载前重置路由:// 重置路由 function resetRouter() { const newRouter = createRouter(); router.matcher = newRouter.matcher; // 替换路由匹配器 } -
菜单生成
动态路由通常需要配合动态菜单生成。可以通过遍历过滤后的路由生成菜单数据。 -
404 路由处理
动态路由加载后,需确保 404 路由位于最后,否则会优先匹配。 -
服务端返回路由
更严格的权限控制可由服务端返回路由结构,前端直接解析后动态加载。
完整代码示例
Vue 动态权限路由示例仓库 提供了更完整的实现参考。







