XYGo Admin 动态路由 + RBAC:一套代码搞定角色权限到按钮级控制
后台管理系统最头疼的需求是什么?权限。不是登录能不能做——能做的一大把——是做到菜单动态加载、按钮级显隐、字段级数据过滤这三级,而且前端后端联动不出岔子。
用了 XYGo Admin 之后,这套东西基本不用从头写了。
双路由体系:前台和后台互不干扰
XYGo Admin 的路由设计很干净——前台门户和后台管理完全隔开:
| 路由 | 前缀 | 模式 |
|---|---|---|
| 前台门户 | / | 静态注册 |
| 后台管理 | /admin | 动态加载 |
前台就是首页、文档、社区、会员中心这些,router/frontend/ 里写死的。后台才是重头戏:用户登录后,前端调后端接口拿菜单 JSON,然后动态注册 Vue Router 路由——不是那种把所有路由全注册再用 meta.roles 筛的伪动态,是真的从数据库菜单表读出来、转成路由对象、addRoute 进去。
那些没权限的页面,在前端路由表里根本不存在,连路径都访问不了。
RBAC 三级权限:从角色到字段
第一级:角色权限(RBAC)
超级管理员 R_SUPER 拥有所有权限,不受校验限制。普通管理员和自定义角色的权限,由管理员在后台分配菜单树决定——勾哪些菜单,角色就有哪些页面。
流程很直观:创建角色 → 勾菜单 → 分配用户 → 登录后后端返回菜单 → 前端注册路由。
第二级:按钮级权限
这个最实用。在后台「菜单管理」里,每个页面可以挂「按钮」类型的子节点,配权限标识如 add、edit、delete、export。前端直接用 v-auth 指令控制:
<!-- 有 add 权限才显示 -->
<ElButton v-auth="'add'" type="primary">新增</ElButton>
<!-- 满足任一即可 -->
<ElButton v-auth="['edit', 'update']" type="primary">编辑</ElButton>
v-auth 的逻辑很简单:取当前路由 meta.authList,判断有没有指定权限,没有就直接从 DOM 移除该元素。还有 v-roles 指令可以按角色控制——比如超级管理员专属面板。
第三级:字段级权限
这一层控制数据字段的可见性和可编辑性。在「字段权限」管理里配好模块→角色→字段规则(可见/可编辑/隐藏),后端通过 admin_field_perm 表在查询和更新时自动过滤字段。敏感字段对不同角色展示不同内容,数据安全上多一层保障。
请求进来时的校验链
请求 → AdminAuth 中间件 → 解析 JWT → 获取角色
→ R_SUPER?直接放行
→ 检查路径是否在角色菜单权限中
→ 有权限:继续 → 无权限:403
超级管理员一路绿灯,其他角色逐级校验,没有弯弯绕绕。
路由工具链
前端路由这块不是零散的几行代码,是一套完整的工具类:
- RouteRegistry:动态注册和卸载路由
- ComponentLoader:组件按需懒加载
- RouteTransformer:把后端菜单 JSON 转成 Vue Router 路由对象
- RoutePermissionValidator:路由级权限校验
- IframeRouteManager:内嵌页面路由管理
路由守卫也分了前后置:beforeEach 做白名单放行和动态路由加载,afterEach 更新标题关 loading。整套流程不用自己拼,开箱就能跑。
总结
很多 Vue3 后台框架的权限方案只有菜单隐藏那一层,按钮级和字段级都得自己补。XYGo Admin 把这三层都做进了标准流程里,动态路由不是「预注册 + 前端筛选」的变体,是真从数据库读菜单再注册。搭配 GoFrame 后端的 AdminAuth 中间件,前后端权限校验逻辑一致,不会出现前端藏了按钮但接口还能调的尴尬。
XYGo Admin 官方文档 里有完整示例,拉下来跑一下就能看到效果。