后台菜单常常由服务端下发:不同角色看到的入口不同,新增页面也不必重新发版。前端要做的不是“照着渲染”,而是把菜单、路由与按钮三处的权限收紧到同一套规则。

菜单契约

菜单按“分组 + 条目”下发。条目里带路径、文案(或文案 key)、图标、所属分组、排序、隐藏标记、权限码与子菜单;分组决定侧栏顺序,层级上限四层,避免接口返回的病态嵌套把侧栏撑爆。

外链条目单独声明地址与打开方式:新窗口、当前窗口或内嵌。内嵌只对允许被内嵌的站点有效——对方发了 X-Frame-Options: DENY 时,嵌进去只会是空白。

容错也要放在前端:异常路径、未知图标、超出层级的子项都会被规整,并留下可读的警告清单。接真实接口时先看这份清单,而不是等用户报错。

路由只认已注册的页面

动态路由的组件来自本地注册表:接口只能引用已注册的页面,不能靠下发的数据新增代码。未登录或没有权限的地址会落到登录页或 403,而不是白屏。

三处一起生效

  • 菜单:按权限码过滤可见条目,没有权限的入口不显示。
  • 路由:直接敲 URL 进来的同样会被拦下,落到 403。
  • 按钮:<Can permission="customer:create"> 控制新建、导出这类操作,无权限时给出禁用态而不是静默失败。

权限码支持 *(全部)、module:*(模块内全部)与精确匹配三种写法,角色差异可以用一份清单表达。文档站的「动态菜单与权限」专题列出了完整契约;在线演示里可以用两个测试账号对比:同一个地址,管理员能看到操作日志,测试账号落 403。