vue router权限实现
Vue Router 权限实现方案
Vue Router 的权限控制通常基于用户角色或权限标识,限制用户访问特定路由。以下是几种常见实现方式:
路由守卫(全局前置守卫)
利用 router.beforeEach 全局守卫进行权限校验,在路由跳转前拦截并验证权限:
router.beforeEach((to, from, next) => {
const userRole = localStorage.getItem('userRole'); // 获取用户角色
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const requiredRole = to.meta.role;
if (requiresAuth && !userRole) {
next('/login'); // 未登录跳转登录页
} else if (requiredRole && requiredRole !== userRole) {
next('/403'); // 无权限跳转403页面
} else {
next(); // 放行
}
});
动态路由表
根据用户权限动态生成路由表,仅加载有权限的路由:
// 定义基础路由(所有用户可见)
const constantRoutes = [
{ path: '/login', component: Login },
{ path: '/404', component: NotFound }
];
// 定义动态路由(按权限加载)
const asyncRoutes = [
{ path: '/admin', component: Admin, meta: { role: 'admin' } },
{ path: '/user', component: User, meta: { role: ['admin', 'user'] } }
];
// 根据权限过滤路由
function filterRoutes(routes, roles) {
return routes.filter(route => {
if (route.meta && route.meta.role) {
return roles.some(role => route.meta.role.includes(role));
}
return true;
});
}
// 初始化路由
const router = new VueRouter({ routes: constantRoutes });
// 登录后动态添加路由
const allowedRoutes = filterRoutes(asyncRoutes, ['user']);
router.addRoutes(allowedRoutes);
组件级权限控制
在组件内部进行细粒度权限校验,结合自定义指令或函数:
// 自定义权限指令
Vue.directive('permission', {
inserted(el, binding) {
const userRole = localStorage.getItem('userRole');
if (binding.value && !binding.value.includes(userRole)) {
el.parentNode.removeChild(el); // 无权限则移除元素
}
}
});
// 使用方式
<button v-permission="['admin']">管理员按钮</button>
权限元信息配置
通过路由的 meta 字段声明权限要求:
const routes = [
{
path: '/dashboard',
component: Dashboard,
meta: {
requiresAuth: true,
roles: ['admin', 'editor']
}
}
];
服务端权限校验
对于高安全性场景,应在服务端进行二次校验:
// 前端请求时携带权限信息
axios.interceptors.request.use(config => {
config.headers['X-User-Role'] = localStorage.getItem('userRole');
return config;
});
// 后端返回路由配置
axios.get('/api/routes').then(response => {
router.addRoutes(response.data.routes);
});
错误处理
实现统一的权限错误处理机制:
router.onError(error => {
if (error.name === 'NavigationDuplicated') {
return;
}
if (error.message.includes('Failed to resolve async component')) {
router.push('/403');
}
});
最佳实践建议
- 权限数据应持久化存储(如 Vuex + localStorage)
- 敏感路由建议服务端渲染时也进行校验
- 动态路由需考虑刷新页面时的重新初始化问题
- 404页面应作为保底路由最后添加
以上方案可根据实际项目需求组合使用,实现从全局到组件级别的完整权限控制体系。







