Vue计算属性实现动态权限控制,核心是将“用户角色→可见菜单项”映射封装为响应式computed,通过MENU_PERMISSIONS常量定义角色权限,结合Pinia获取响应式角色,动态过滤asyncRoutes生成accessibleMenus供模板渲染。
Vue计算属性实现动态权限控制,核心是把「用户角色 → 可见菜单项」的映射逻辑封装成响应式计算属性,避免在模板里写一堆
判断,也方便统一维护和测试。
定义角色与菜单权限的映射关系
先明确哪些角色能访问哪些菜单。例如:
管理员(
admin
):可访问「仪表盘、用户管理、系统设置」
运营(
operator
):可访问「仪表盘、用户管理、数据报表」
只读用户(
viewer
):仅可访问「仪表盘、数据报表」
建议将映射表抽离为常量对象,放在独立文件中(如
),便于复用:
在组件中获取当前用户角色
通常从 Pinia 或 Vuex 的 store 中读取,确保它是响应式的:
立即学习
“
前端免费学习笔记(深入)
”;
注意:如果角色来自异步登录接口,必须通过
包裹,否则后续菜单渲染不会自动更新。
Vue-router参考手册
Vue-router参考手册下载
下载
用 computed 动态生成可访问菜单列表
基于角色查表,过滤出当前用户有权限的路由配置:
这样,
就是一份完全响应式的、按角色过滤后的菜单数据,可直接传给侧边栏组件。
模板中渲染动态菜单
使用
遍历
,无需额外判断:
菜单结构变化时,只要更新
或
,整个菜单自动重算、重新渲染。
v-ifpermissions.jsexport const MENU_PERMISSIONS = {
admin: ['/dashboard', '/user', '/system', '/report'],
operator: ['/dashboard', '/user', '/report'],
viewer: ['/dashboard', '/report']
}// Vue 3 Composition API
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const userRole = computed(() => userStore.role)computedimport { MENU_PERMISSIONS } from '@/utils/permissions'
import { asyncRoutes } from '@/router/routes' // 所有需权限的路由配置
const accessibleMenus = computed(() => {
const allowedPaths = MENU_PERMISSIONS[userRole.value] || []
const filterMenu = (routes) => {
return routes.filter(route => {
// 一级菜单:直接匹配 path
if (allowedPaths.includes(route.path)) return true
// 有 children 的菜单:递归检查子项是否至少有一个可见
if (route.children && route.children.length) {
route.children = filterMenu(route.children)
return route.children.length > 0
}
return false
})
}
return filterMenu(asyncRoutes)
})accessibleMenusv-foraccessibleMenus
{{ menu.meta.title }}
{{ child.meta.title }}
{{ menu.meta.title }}
MENU_PERMISSIONSuserStore.role