前段时间写了几篇ant design pro v4服务器控制菜单和路由的文章。有小伙伴说按照文章的方法菜单是拉取下来了。但是,跟使用config.ts控制菜单相比,服务器下发的菜单没有显示菜单图标(Icon)。于是,又花了一点时间解决icon显示的问题,这里来跟大家分享。
我们在这篇文章的基础上进行修改,如有需要请参考下面链接查看:
玩乐儿童编程:Ant design pro v4-服务器菜单和路由权限控制1. 在服务器下发菜单中添加icon字符串
{
"code": 0,
"message": "response successful",
"data": [{
"path": "/overview",
"name": "数据总览",
"icon": "smile",
"children": [{
"path": "/overview/daily",
"name": "analysis12",
"children": null,
"authority": null,
"icon": "smile",
}],
"authority": ["admin", "user"]
}, {
"path": "/function",
"name": "gongneng",
"icon": "smile",
"children": [{
"path": "/function/sign",
"name": "sign111",
"children": null,
"authority": null,
"icon": "smile",
}, {
"path": "/function/task",
"name": "task111",
"children": null,
"authority": ["admin"],
"icon": "smile",
}, {
"path": "/function/pay",
"name": "task111",
"children": null,
"authority": ["admin"],
"icon": "smile",
}],
"authority": null
}]
}
2. 在前端定义枚举映射
import {HomeOutlined, PicLeftOutlined, SmileOutlined, SettingOutlined,} from '@ant-design/icons';
const iconEnum = {
smile: <SmileOutlined />,
home: <HomeOutlined />,
picLeft: <PicLeftOutlined />,
setting: <SettingOutlined />,
};
3. 对服务器下发的菜单数据进行转换(string->Icon)
利用MenuDataItem中icon字段是React.ReactNode的类型
export interface MenuDataItem {
authority?: string[] | string;
children?: MenuDataItem[];
hideChildrenInMenu?: boolean;
hideInMenu?: boolean;
icon?: React.ReactNode;
locale?: string;
name?: string;
key?: string;
path?: string;
[key: string]: any;
parentKeys?: string[];
}
将服务器下发的icon字符串转换为对应的Icon图标
const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
menuList.map(item => {
const localItem = { ...item, icon:iconEnum[item.icon], children: item.children ? menuDataRender(item.children) : [] };
return Authorized.check(item.authority, localItem, null) as MenuDataItem;
});
const serverMenuItem = ():MenuDataItem[]=>{
const transMenuItem :MenuDataItem[] = [];
if(Array.isArray(menuData)){
menuData.forEach((v) => {
const localV = { ...v, children: v.children ? menuDataRender(v.children) : [] , icon:iconEnum[v.icon]};
const localMenuDataItem = Authorized.check(v.authority, localV, null) as MenuDataItem;
transMenuItem.push(localMenuDataItem);
});
}
return transMenuItem;
};
参考文章:
https://github.com/umijs/umi-plugin-antd-icon-config/issues/2