Vue大型项目权限控制与动态路由
大型Vue项目需实现细粒度权限控制,下面梳理核心设计方案。
权限模型设计
角色与权限映射
JavaScript
// constants/permissions.js
export const ROLES = {
ADMIN: 'admin',
MANAGER: 'manager',
USER: 'user'
}
export const PERMISSIONS = {
// 用户模块
'user:list': '查看用户列表',
'user:create': '创建用户',
'user:edit': '编辑用户',
'user:delete': '删除用户',
// 订单模块
'order:list': '查看订单',
'order:export': '导出订单'
}
// 角色权限映射表
export const ROLE_PERMISSIONS = {
admin: Object.keys(PERMISSIONS),
manager: ['user:list', 'order:list', 'order:export'],
user: ['order:list']
}
动态路由生成
路由过滤逻辑
JavaScript
// router/guards.js
import { ROLE_PERMISSIONS } from '@/constants/permissions'
// 所有可能路由表(含权限标识)
const asyncRoutes = [
{
path: '/user',
component: () => import('@/views/user/index.vue'),
meta: { permission: 'user:list', title: '用户管理' }
},
{
path: '/order',
component: () => import('@/views/order/index.vue'),
meta: { permission: 'order:list', title: '订单管理' }
}
]
// 根据权限过滤路由
export function filterRoutesByPermission(role) {
const permissions = ROLE_PERMISSIONS[role] || []
return asyncRoutes.filter(route => {
if (!route.meta?.permission) return true
return permissions.includes(route.meta.permission)
})
}
// 动态添加路由
export async function addDynamicRoutes(router, role) {
const allowedRoutes = filterRoutesByPermission(role)
allowedRoutes.forEach(route => router.addRoute('default', route))
}
路由守卫集成
JavaScript
// router/index.js
import { useUserStore } from '@/store/modules/user'
import { addDynamicRoutes } from './guards'
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore()
// 公开路由直接放行
if (to.meta.public) return next()
// 未登录跳转登录页
if (!userStore.token) {
return next({ name: 'Login', query: { redirect: to.fullPath } })
}
// 已登录但未加载动态路由
if (!userStore.routesLoaded) {
await addDynamicRoutes(router, userStore.role)
userStore.routesLoaded = true
return next({ ...to, replace: true })
}
next()
})
按钮级权限控制
权限指令
JavaScript
// directives/permission.js
export const permission = {
mounted(el, binding) {
const { value } = binding
const userStore = useUserStore()
const permissions = userStore.permissions
if (value && !permissions.includes(value)) {
el.parentNode?.removeChild(el)
}
}
}
// 使用方式
// <button v-permission="'user:create'">新增用户</button>
权限检查Hook
JavaScript
// composables/usePermission.js
import { computed } from 'vue'
import { useUserStore } from '@/store/modules/user'
export function usePermission() {
const userStore = useUserStore()
const hasPermission = (key) => {
return userStore.permissions.includes(key)
}
const hasAnyPermission = (keys) => {
return keys.some(key => hasPermission(key))
}
return { hasPermission, hasAnyPermission }
}
权限对比
| 粒度 | 实现方式 | 适用场景 |
|---|---|---|
| 页面级 | 动态路由过滤 | 菜单权限控制 |
| 按钮级 | 自定义指令/v-if | 操作按钮显隐 |
| 数据级 | 接口参数过滤 | 行级数据权限 |
要点总结
- 权限模型采用角色-权限映射表,便于集中管理
- 动态路由在登录后首次加载时添加,避免重复注册
- 按钮级权限使用自定义指令实现DOM移除
- 权限检查封装为composable,支持逻辑复用
- 权限变更时需重置路由表并重新加载
存放路径: articles/VUE/专家/大型项目架构分层设计/权限控制与动态路由.md
📝 发现内容有误?点击此处直接编辑