前言:
在Ant Design Pro中菜单是写在配置文件中,菜单是静态的数据,当项目打包之后就不可以进行修改。不支持动态菜单,对管理系统来说不是非常友好。本篇文章将会介绍一下,如何在Ant Design Pro 中实现动态获取菜单。
正文:
Ant Design Pro是基于UmiJs企业级前端框架进行的开发。在UmiJs的app.ts文件中,可以运行时配置文件,它扩展运行时的能力,比如修改路由、修改Render方法等。所以,实现动态获取菜单可以在app.ts文件配置。 在Ant Design Pro中是没有app.ts文件,需要我们在src目录下新建一个app.ts文件。app.ts文件中,主要需要修改render()、patchRoutes()两个方法。
1.app.ts文件:
import dynamic from 'dva/dynamic';
import {listRouteData} from '@/services/system/menu'
import {history} from "@@/core/history";
/**
* 路由实体
*/
interface RouteProps {
path: string,
name: string,
icon?: string,
component?: string,
authority?: string[], // 根据localStorage的值,过滤菜单,只能控制到菜单,颗粒度太大,废弃
permission?: PermissionProps[],
routes?: RouteProps[],
}
/**
* 权限实体
*/
interface PermissionProps {
name: string,
key: string,
}
/**
* 路由数组
*/
let routeArray: RouteProps[] = [];
/**
* 解析路由
*
* @param authRouteArray
*/
const parseRoutes = (authRouteArray: any) => {
return (authRouteArray || []).map((item: any) => {
if (item.routes && item.routes.length > 0) {
return {
path: item.path,
name: item.name,
icon: item.icon,
authority: item.authority,
routes: parseRoutes(item.routes),
};
}
return {
path: item.path,
name: item.name,
icon: item.icon,
authority: item.authority,
permission: item.permission,
component: dynamic({component: () => import(`@/pages${item.component}/index.tsx`)}),
};
});
}
/**
* 动态修改路由
*
* @param routes
*/
export function patchRoutes({routes}: any) {
// console.log(routes)
const curRouteArray = routes[0].routes[1].routes;
curRouteArray.length = 0;
// 添加首页
curRouteArray.push({
name: 'home',
icon: 'home',
path: '/home',
component: dynamic({component: () => import(`@/pages/home`)}),
});
parseRoutes(routeArray).forEach((item: any) => {
curRouteArray.push(item);
});
curRouteArray.push({
path: '/',
redirect: '/home',
});
curRouteArray.push({
component: dynamic({component: () => import(`@/pages/exception/404`)}),
});
// console.log(curRouteArray);
}
/**
* 该方法会在patchRoutes之前进行执行。
* @param oldRender
*/
export function render(oldRender: any) {
// 获取路由
const {pathname} = history.location;
if (pathname !== '/user/login') {
// console.log(pathname)
listRouteData().then((data: any) => {
// console.log(data)
routeArray = data?.data || [];
oldRender();
})
}else {
oldRender();
}
}
2.获取菜单的后台接口menu.ts:
import request from '@/utils/request';
import api from '@/utils/api';
/**
* 获取路由
*/
export async function listRouteData(): Promise<any> {
return request(api.listRoute, {
method: 'GET',
});
}