要从服务端请求菜单可以在src下的app.tsx中修改运行时配置,menuDataRender或者menu,
在本人测试中如果使用menu项配置可以实现从服务端请求代码,不过locale:false无效,菜单名称还是会从国际化配置文件中读取。使用menuDataRender配置则设置locale:false即可不从国际化配置文件中读取。
注意,以下代码只会修改左侧菜单的现实,至于菜单项和组件的关系仍需要在config/routes.ts中配置。
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
/*menu: {
// 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
params: {
username: initialState?.currentUser?.user.userName,
},
request: async (params, defaultMenuData) => {
// console.log(params, defaultMenuData)
console.log('customMenuData: ', initialState?.customMenuData)
const menuData = initialState?.customMenuData;
const menuDataIcon = menuData?.map(ele => {
if (ele.iconName) {
const iconNode: React.ReactNode = iconMapping[ele.iconName];
if (iconNode) {
ele.icon = iconNode;
}
}
if (ele.name === '系统管理') {
console.log('ele?.routes?[0]: ', ele?.routes||[][0]);
const component = (ele?.routes||[])[0].component;
// console.log('component:', component)
(ele?.routes||[])[0].component = dynamic({ loader: () => import(component||''), loading: LoadingComponent})
}
// ele?.routes||[][0].component = dynamic({ loader: () => import(ele?.routes||[][0].component||''), loading: LoadingComponent})
// ele.icon = <BorderLeftOutlined />
return ele;
})
// initialState.currentUser 中包含了所有用户信息
// const menuData = await fetchMenuData();
const data = [...defaultMenuData, ...menuDataIcon||[]]
console.log('menu data: ', data)
console.log('iconMap: ', iconMap)
console.log('iconMap: ', iconMap['BorderLeftOutlined'])
return data;
},
},*/
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
links: isDev
? [
<Link to="/umi/plugin/openapi" target="_blank">
<LinkOutlined />
<span>OpenAPI 文档</span>
</Link>,
<Link to="/~docs">
<BookOutlined />
<span>业务组件文档</span>
</Link>,
]
: [],
menuDataRender: (menuItems) => {
const resMenuData = initialState?.customMenuData||[];
const menuDataIcon = handleIconAndComponent(resMenuData);
const data = [...menuDataIcon||[]]
return data;
},
menuHeaderRender: undefined,
menuItemRender: (menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || !menuItemProps.path) {
return defaultDom;
}
// 支持二级菜单显示icon
return (
<Link to={menuItemProps.path}>
{menuItemProps.pro_layout_parentKeys
&& menuItemProps.pro_layout_parentKeys.length > 0 &&
menuItemProps.icon}{defaultDom}
</Link>
);
},
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
// 增加一个 loading 的状态
childrenRender: (children, props) => {
return (
<>
{children}
{!props.location?.pathname?.includes('/login') && (
<SettingDrawer
enableDarkTheme
settings={initialState?.settings}
onSettingChange={(settings) => {
setInitialState((preInitialState) => ({
...preInitialState,
settings,
}));
}}
/>
)}
</>
);
},
...initialState?.settings,
};
};
handleIconAndComponent: 处理菜单图标问题
import {SYSTEM} from "@/services/system/typings";
import React from "react";
import * as allIcons from '@ant-design/icons';
export function handleIconAndComponent(routes: SYSTEM.Router[]) {
return routes.map(ele => {
if (ele.iconName) {
const iconNode: React.ReactNode = React.createElement(allIcons[ele.iconName]);
if (iconNode) {
ele.icon = iconNode;
}
}
delete ele.component
if (ele.routes && ele.routes.length > 0) {
handleIconAndComponent(ele.routes);
}
return ele;
})
}