导航守卫不直接渲染菜单,而是与响应式角色状态配合实现多级菜单可见性过滤;角色须存入pinia等响应式存储,菜单用computed动态过滤,路由守卫二次校验权限,统一数据源支撑多位置菜单渲染。

导航守卫本身不直接渲染菜单,但它和用户角色列表配合,能驱动多级菜单的可见性过滤——关键在于把角色信息作为响应式输入,通过计算属性或工具函数生成可访问的菜单结构,再由菜单组件消费。
角色数据要提前注入并保持响应式
登录成功后,从后端获取的用户角色(如 ['admin', 'editor'])必须存入响应式状态(例如 Pinia store 中的 userRoles),不能只是普通变量。菜单组件依赖这个状态自动重算,否则角色变了菜单却不更新。
- 推荐用
ref或store管理角色,避免直接挂载到window或全局对象 - 如果后端返回的是权限码(如
['system:user:list', 'system:menu:edit']),也建议统一转为角色数组或合并进同一响应式字段,简化后续判断逻辑
菜单过滤逻辑放在计算属性里更可靠
不要在菜单组件的 mounted 里一次性过滤,而应使用 computed 封装过滤逻辑。它会自动监听角色变化,并返回当前用户可见的多级菜单树。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 遍历原始菜单配置(含
children的嵌套结构),逐层检查每项的meta.roles - 只保留角色匹配的节点;若父节点无权限但子节点有权限,通常不显示该父级(除非设计要求“透出子项”)
- 示例判断:
item.meta?.roles?.some(role => userRoles.value.includes(role))
路由守卫负责兜底跳转拦截
菜单可见 ≠ 路由可访问。即使菜单没显示某项,用户仍可能手动输入 URL。这时 router.beforeEach 需二次校验:
- 提取目标路由的
to.meta.roles - 比对当前
userRoles.value是否满足任一角色 - 不满足则跳转到
/403或首页,避免白屏或越权访问
多级菜单渲染时复用同一套权限规则
无论是侧边栏还是顶部三级导航,都应基于同一个过滤后的菜单数据源渲染。不需要为不同位置写两套逻辑:
- 菜单组件接收过滤后的
filteredMenuList作为 prop - 递归渲染时,每一层都沿用相同的权限判断方式(不额外查角色)
- 若需支持“始终显示某菜单项”(如首页),可在
meta中加showAlways: true字段绕过角色检查
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









