背景
复杂的权限在前端不方便控制,将路由保存到后端,经过后端鉴权后返回相应的路由。
umi 版本: 2.x
注意
该方法适用于 umi 3.x,但是需要注意,
patchRoutes
的参数与 2.x 不同。
方案
使用 umi 提供的 运行时配置 功能,结合 patchRoutes
和 render
接口,动态修改路由。
-
在项目根目录创建
app.js
文件,该文件为 umi 的运行时配置文件。config 目录下以及
.umirc.js
文件都是编译时配置。 -
编写
patchRoutes
和render
方法。let normalizedRoutes; // umi3.x 需要将 routes 选项从第一个参数中解构: patchRoutes({ routes }) {} export function patchRoutes(routes) { if (normalizedRoutes) { mergeRoutes(normalizedRoutes, routes); } } // oldRender 至少需要被调用一次 export function render(oldRender) { fetch('/api/routes').then(res=>res.json()).then((res) => { normalizedRoutes = res.routes; oldRender(); }) } const mergeRoutes = (routes, parentRoute) => { if (!Array.isArray(routes)) return []; return routes.map(route => { if (route.path) { route.path = route.path.startsWith('/') ? route.path : `${parentRoute?.path || ''}/${route.path}`; } if (route.component) { route.component = (component => { if (typeof component === 'function') { return component; } // eslint-disable-next-line global-require, import/no-dynamic-require, prefer-template return require('./pages/' + component.substr(component.indexOf('/') + 1)).default; })(route.component); } if (route.routes) { route.routes = mergeRoutes(route.routes, route); } return route; }); };
注意
render
函数在patchRoutes
之前执行,所以要在render
中获取后端返回的路由数据。