后台菜单常常由服务端下发:不同角色看到的入口不同,新增页面也不必重新发版。前端要做的不是“照着渲染”,而是把菜单、路由与按钮三处的权限收紧到同一套规则。
菜单契约
菜单按“分组 + 条目”下发。条目里带路径、文案(或文案 key)、图标、所属分组、排序、隐藏标记、权限码与子菜单;分组决定侧栏顺序,层级上限四层,避免接口返回的病态嵌套把侧栏撑爆。
外链条目单独声明地址与打开方式:新窗口、当前窗口或内嵌。内嵌只对允许被内嵌的站点有效——对方发了 X-Frame-Options: DENY 时,嵌进去只会是空白。
容错也要放在前端:异常路径、未知图标、超出层级的子项都会被规整,并留下可读的警告清单。接真实接口时先看这份清单,而不是等用户报错。
路由只认已注册的页面
动态路由的组件来自本地注册表:接口只能引用已注册的页面,不能靠下发的数据新增代码。未登录或没有权限的地址会落到登录页或 403,而不是白屏。
三处一起生效
- 菜单:按权限码过滤可见条目,没有权限的入口不显示。
- 路由:直接敲 URL 进来的同样会被拦下,落到 403。
- 按钮:
<Can permission="customer:create">控制新建、导出这类操作,无权限时给出禁用态而不是静默失败。
权限码支持 *(全部)、module:*(模块内全部)与精确匹配三种写法,角色差异可以用一份清单表达。文档站的「动态菜单与权限」专题列出了完整契约;在线演示里可以用两个测试账号对比:同一个地址,管理员能看到操作日志,测试账号落 403。