antDesign实现动态菜单+动态路由
配置菜单路由权限有几种方式:
- 防君子不防小人 菜单栏虽然没有页面权限,但可以输入url访问没有权限的页面
- 统统防着 这就需要动态路由
一、实现动态菜单
待更新
二、实现动态路由
实现思路是使用Umi的 提供了几个方法,其中patchRender和render配置配合使用,请求服务端根据响应动态更新路由
patchRender({ routes }):用于修改路由 render(oldRender):用于渲染之前做权限校验
基本步骤
- src目录下新建app.ts
- app.ts中重写patchRender,render方法
// authRoutes用于暂存render请求的路由配置信息
let authRoutes: any[];
export function patchRoutes({
routes }) {
authRoutes.forEach(route => routes.push(route));
}
export function render(oldRender) {
fetch(/XXX/XXX)
.then(res => res.json())
.then(res => {
authRoutes = res.result.menus;
oldRender();
});
}
但到此结束发现,页面是空白页,需要parseRoutes方法解析下数据,仍然写在app.ts中。
改写patchRoutes。
export function patchRoutes({
routes }) {
parseRoutes(authRoutes).forEach(route => routes.push(route));
}
登录后动态获取路由
基本思路是在登录后获取路由,再强制刷新一下,由patchRoutes修改路由。 获取路由后的处理,设置sessionStorage的LOADED为标志,若非已加载就暂存MENUS
// 请求路由接口:返回res
if (sessionStorage.getItem(LOADED) !== 1) {
sessionStorage.setItem(LOADED, 1);
sessionStorage.setItem(MENUS, JSON.stringify(res.result.menus));
window.location.reload();
}
app.ts中render方法需要修改
export function render(oldRender: () => void) {
const menus = JSON.parse(sessionStorage.getItem(MENUS) ?? []);
if (menus?.length > 0) {
authRoutes = menus;
oldRender();
} else {
oldRender();
}
}
这样是实现了登录后动态修改路由,但还需要登出后删除LOADED
sessionStorage.removeItem(LOADED); sessionStorage.removeItem(MENUS);
此外,还有一种方法
let extraRoutes;
export function patchRoutes({
routes }) {
routes[1].routes = extraRoutes.concat(routes[1].routes);
}
export function render(oldRender) {
window.umi_reload = ()=>{
//根据用户请求菜单数据
await xxx //读取数据放入extraRoutes
oldRender();
}
window.umi_reload();
}
