技术

Umi 4 权限控制:Access 与 InitialState 的执行顺序陷阱

umi框架的项目中可能会遇到的问题

在 Umi 4 项目中,我们通常使用官方插件 @umi/plugin-access 来控制菜单和路由的显示/隐藏。这些权限通常依赖后端返回的权限标识(例如:aiPermissionList)。

如果权限数据的获取时机不当,会导致 access 模块在校验时无法读取到最新的数据,从而导致展示了错误的菜单路由。

1. 核心问题:执行顺序冲突

如果将权限请求放在常规组件(如 Layout)的 useEffect 中,其执行顺序会导致权限失效。

错误的执行顺序

  1. 应用启动
  2. 执行 getInitialState():此时未请求权限,状态为空。
  3. access.ts 实例化:插件读取 initialState,此时权限列表为空,路由/菜单被过滤隐藏。
  4. Layout 组件渲染:组件挂载到页面。
  5. useEffect 执行:触发后端请求,异步将权限存入 Store。
  6. 结果access 早已完成判断,异步更新的权限无法实时反哺到已生成的路由树中

2. 解决方案:预加载权限数据

为了确保 access 能够正确识别权限,必须在 access.ts 运行之前完成权限数据的获取。

正确的执行顺序

  1. 应用启动
  2. 执行 getInitialState()
    • 内部调用 fetchPermissions() 请求后端接口。
    • 阻塞等待接口返回后,将 aiPermissionList 存入初始状态对象。
  3. access.ts 实例化
    • 自动获取到包含权限数据的 initialState
  4. Layout 组件渲染
    • 菜单和路由已根据正确的权限完成过滤,页面正常展示。

白屏

嘿,聪明的你在研究的时候可能发现页面的白屏时间变长了,这是因为由于 getInitialState 在 Umi 4 中具有阻塞渲染的特性,getInitialState发生在layout组件渲染之前,所以将接口请求提前会导致应用白屏时间变长.

你需要使用umi的配置加一个loading页面或者动画^^ 不得不吐槽umi的垃圾文档,不像人类写的...