vue-cms 动态路由实现原理:从 permission 模块到 addRoutes 的完整链路

📅 2026/8/17 21:40:38
vue-cms 动态路由实现原理:从 permission 模块到 addRoutes 的完整链路
vue-cms 动态路由实现原理从 permission 模块到 addRoutes 的完整链路【免费下载链接】vue-cms基于 Vue 和 ElementUI 构建的一个企业级后台管理系统项目地址: https://gitcode.com/gh_mirrors/vu/vue-cmsvue-cms 是一个基于 Vue 2、Vuex 和 ElementUI 构建的企业级后台管理系统而动态路由也叫权限路由正是它权限体系中最核心的机制。很多前端新手在搭建后台管理系统时都会卡在不同角色登录后看到不同菜单这一步。本文将从permission模块出发一路追踪到router.addRoutes的动态挂载把 vue-cms 动态路由实现原理的完整链路一次讲透帮你彻底搞懂权限路由的来龙去脉。一、为什么后台管理系统需要动态路由后台管理系统通常存在多种角色管理员、普通用户、运营人员……每个人的可访问页面都不一样。如果把所有路由一股脑注册进去用户就能通过地址栏直接输入 URL 越权访问安全性和体验都大打折扣。动态路由权限路由的解决思路是前端提前写好一份动态路由表登录后根据后端返回的权限菜单把用户没有权限的路由过滤掉再用router.addRoutes()动态注册到 Vue Router 中。这样既保证了菜单按角色渲染也实现了页面级的路由拦截。vue-cms 的权限模块设计涵盖了路由、菜单、页面、按钮四级权限非常值得参考。二、vue-cms 动态路由的三大路由表打开src/router/index.js可以看到 vue-cms 把路由拆成了三份这是理解动态路由实现原理的基石constantRoutes基础路由任何角色都能访问如登录页/login、首页/home、重定向页在创建 Router 时就注册asyncRoutes动态路由如表格、图表、富文本等功能页面需要按权限过滤后才注册endBasicRoutes末尾路由404、无权限、通配*兜底页面永远追加在动态路由最后防止误匹配。三者的注册顺序是[基础路由] [动态路由] [末尾路由]这个顺序保证了通配符路由不会提前拦截正常页面。三、第一步登录时把权限数据写入 sessionStorage动态路由的起点不在 router 里而在用户登录的那一刻。看src/store/modules/user.js中的loginaction登录接口返回的数据里除了 token 和用户信息还包含一份permissions菜单、页面、按钮的权限列表。vue-cms 会把它通过saveToSession(userRoutes, data.permissions)存进 sessionStorage存储工具封装在src/common/session-storage.js统一挂在__vue_cms__键下方便刷新页面后恢复权限。注意这里存的是后端返回的权限地址列表而不是路由对象本身。菜单权限用type: 1/2标记按钮权限用type: 3标记类型判断封装在src/utils/validate.js中。四、第二步路由守卫中判断动态路由是否已加载用户带着 token 跳转任何页面时都会先经过src/permission.js里的全局前置守卫router.beforeEach。这里的判断逻辑是整个 vue-cms 动态路由实现原理的枢纽没有 token直接清空 session白名单页面放行其余跳转登录页有 token 且store.getters.addRoutes.length 0说明动态路由还没加载过此时先从 sessionStorage 里取userRoutes如果为空说明数据异常直接重置 token 重新登录数据正常则触发store.dispatch(permission/generateRoutes, userRoutes)生成路由。五、第三步permission 模块递归过滤生成可访问路由关键动作发生在src/store/modules/permission.js的generateRoutesaction 中vue-cms 动态路由的核心过滤逻辑就在这里先用isMenuPermissionByType筛出菜单/页面权限type 1/2用isBtnPermissionByType筛出按钮权限type 3分别存入 state调用filterAsyncRoutes(asyncRoutes, menuRoles)对前端路由表做递归过滤核心函数hasPermission判断后端返回的address是否与前端路由的path完全匹配匹配则保留该路由子路由同样递归过滤只要父级有权限或子级过滤后仍有内容该路由就会被保留过滤完成后把endBasicRoutes追加到最后commit(SET_ROUTES)写入 Vuexstate.routes constantRoutes.concat(routes)state.addRoutes routes。这样一来asyncRoutes这份全量路由表就被裁剪成了当前用户真正有权限的路由列表。六、第四步router.addRoutes 动态挂载与 next 技巧路由对象生成后回到permission.js的守卫里执行最后两步router.addRoutes(accessRoutes) // 动态注册权限路由 next({ ...to, replace: true }) // 重新触发本次导航这里有一个新手容易踩坑的点router.addRoutes是异步生效的直接next()可能导致当前导航匹配不到刚加的路由。vue-cms 采用了经典解法——用next({ ...to, replace: true })把当前地址再导航一次此时路由已注册完毕就能正确匹配到目标页面且不会留下多余的浏览历史记录。七、菜单渲染addRoutes 与侧边栏的联动动态路由不止影响跳转还驱动着左侧菜单的生成。侧边栏布局src/layout/library/default.vue通过 Vuex getter 里的routers读取数据routers state.permission.routes constantRoutes.concat(addRoutes)也就是说侧边栏渲染的菜单正是基础路由 当前用户权限路由的合集。用户权限不同addRoutes不同菜单自然不同。meta里的icon、title字段则决定了菜单图标和国际化文案hidden: true的路由如 404不会出现在菜单中。八、退出登录resetRouter 正确重置动态路由动态路由是一次性注入的如果不重置用户切换账号后旧路由依然存在权限就会串号。vue-cms 的处理非常规范用户登出时执行src/store/modules/user.js的logout清理 token 和 sessionStorage同时在resetToken中调用resetRouter()——这个函数在src/router/index.js中通过new Router()重新创建实例并替换router.matcher把之前 addRoutes 注册的权限路由全部清空恢复到初始状态。这一步保证了换账号、重新登录后动态路由会重新按新权限生成。九、vue-cms 动态路由实现原理完整链路总结最后用一张流程图收尾记住这条完整的调用链登录成功 → user 模块保存 permissions 到 sessionStorage ↓ 路由守卫 beforeEach 检测 addRoutes 为空 ↓ 从 session 读取 userRoutes ↓ dispatch permission/generateRoutes ↓ filterAsyncRoutes 递归过滤 → 追加 endBasicRoutes ↓ commit SET_ROUTES → 更新 Vuex 中的 routes 和 addRoutes ↓ router.addRoutes 动态注册 next({...to, replace:true}) ↓ 侧边栏按 routers 渲染菜单 ↓ 退出登录 → resetToken → resetRouter 清空动态路由核心代码就散落在四个文件中permission.js全局守卫、router/index.js三份路由表 resetRouter、store/modules/permission.js过滤与生成、store/modules/user.js登录与登出。把这条链路读懂你就能在自己的 Vue 后台管理系统里复刻一套完整的动态路由权限方案了。【免费下载链接】vue-cms基于 Vue 和 ElementUI 构建的一个企业级后台管理系统项目地址: https://gitcode.com/gh_mirrors/vu/vue-cms创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考