登录后立即获取权限路由数据存入pinia并动态添加至vue router,刷新时自动恢复、登出时彻底清理,菜单渲染与守卫权限控制分离,确保路由存在性校验为唯一可信权限入口。

核心是登录后取权限数据 → 存入 Pinia → 解析并添加到 router → 渲染菜单。整个流程必须在跳转前完成,否则会白屏或 404;刷新后需自动恢复,登出时要清理干净。
权限数据获取与状态管理
登录成功后,立即请求后端返回结构化路由/菜单数据(如含 path、name、component、children、meta.title 等字段的数组),不要只存角色名(如 "admin")。
- 新建 authStore,用 Pinia 管理
token、rawRoutes、menuList - 建议开启
persist: true持久化,避免刷新重拉;敏感场景改用sessionStorage -
component字段需约定格式(如"sys/User"),对应import(`@/views${item.component}.vue`)
动态挂载路由到 Vue Router
不能等页面打开再注册,必须在导航触发前就位。推荐在 router.beforeEach 中统一兜底处理。
- 判断是否已加载:检查
authStore.rawRoutes.length > 0且基础路由(如home)存在 - 遍历
rawRoutes,逐条调用router.addRoute(route);嵌套路由需先确保父级已注册(如先加dashboard,再加其子项) - 每条路由建议加
meta: { dynamic: true }标记,便于后续识别和清理 - 挂载完成后用
next({ to, replace: true })替换当前导航,防止守卫重复触发
刷新与登出时的状态维护
刷新后内存清空,但用户仍处于登录态;登出若不清除动态路由,可能造成越权访问。
- 刷新时:守卫中检测 token 存在 + 关键路由缺失 → 触发权限拉取与挂载 → 完成后
next({ path: to.fullPath, replace: true }) - 登出时:调用每个
addRoute返回的清除函数(如const remove = router.addRoute(...)),批量执行remove() - 清理后建议
router.push('/login'),避免停留在无效页面 - 不用
router.getRoutes()判断路由是否存在——它只返回已访问过的活跃路由;应使用router.hasRoute('name')
菜单渲染与权限控制分离
菜单只是视图层展示,真正的权限拦截必须由路由守卫完成,不能依赖点击事件或前端隐藏逻辑。
- 菜单生成:遍历
router.getRoutes(),过滤出meta.showInMenu === true且权限匹配的路由 - 守卫逻辑:不比对角色,而是检查目标路由是否存在;若
!router.hasRoute(to.name),直接重定向到 404 或无权页 - 禁止在菜单点击里做权限判断——用户可直接输入 URL 或刷新页面,守卫才是唯一可信入口
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









