一、BasicLayout.jsx中获取服务端传来的菜单json格式的(需要符合config.js中的路由格式)
/**
* Ant Design Pro v4 use `@ant-design/pro-layout` to handle Layout.
* You can view component api by:
* https://github.com/ant-design/ant-design-pro-layout
*/
import ProLayout, { DefaultFooter, SettingDrawer } from '@ant-design/pro-layout';
import React, { useEffect } from 'react';
import { Link, useIntl, connect } from 'umi';
import { GithubOutlined ,FormOutlined, AccountBookOutlined,UserOutlined,
SmileOutlined, SettingOutlined,WechatOutlined,GiftOutlined,AppstoreOutlined,
TeamOutlined,BarsOutlined,DashboardOutlined,WarningOutlined} from '@ant-design/icons';
import { Result, Button } from 'antd';
import Authorized from '@/utils/Authorized';
import RightContent from '@/components/GlobalHeader/RightContent';
import { getAuthorityFromRouter } from '@/utils/utils';
import logo from '../assets/logo.svg';
const noMatch = (
Go Login
}
/>
);
/** 重点:自定义了一个枚举 图标的方法
原因:后台传过来的icon:string 再菜单中无法显示图标
*/
const iconEnum = {
smile: ,
setting: ,
form: ,
accountBook: ,
wechat: ,
gift: ,
appstore: ,
team: ,
bars: ,
dashboard: ,
warning: ,
user: ,
};
/**
* use Authorized check all menu item
*/
const menuDataRender = menuList =>
menuList.map(item => {
// icon:iconEnum[item.icon] 遍历菜单中图标,转化成可展示的图标
const localItem = { ...item,icon:iconEnum[item.icon], children: item.children ? menuDataRender(item.children) : [] };
return Authorized.check(item.authority, localItem, null);
});
const defaultFooterDom = (
,
href: 'https://github.com/ant-design/ant-design-pro',
blankTarget: true,
},
{
key: 'Ant Design',
title: 'Ant Design',
href: 'https://ant.design',
blankTarget: true,
},
]}
/>
);
const BasicLayout = props => {
const {
dispatch,
children,
settings,
menuData,
location = {
pathname: '/',
},
} = props;
/**
* constructor
*/
useEffect(() => {
if (dispatch) {
dispatch({
type: 'user/fetchCurrent',
});
/** 重点:useEffect 相当于生命周期函数
自己再global.js 中添加一个方法fetchMenu 用来获取服务器传过来菜单列表
*/
dispatch({
type: 'global/fetchMenu',
});
}
}, []);
/**
* init variables
*/
const handleMenuCollapse = payload => {
if (dispatch) {
dispatch({
type: 'global/changeLayoutCollapsed',
payload,
});
}
}; // get children authority
const authorized = getAuthorityFromRouter(props.route.routes, location.pathname || '/') || {
authority: undefined,
};
const { formatMessage } = useIntl();
return (
<>
(
{logoDom}
{titleDom}
)}
onCollapse={handleMenuCollapse}
menuItemRender={(menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || menuItemProps.children || !menuItemProps.path) {
return defaultDom;
}
return {defaultDom};
}}
breadcrumbRender={(routers = []) => [
{
path: '/',
breadcrumbName: formatMessage({
id: 'menu.home',
}),
},
...routers,
]}
itemRender={(route, params, routes, paths) => {
const first = routes.indexOf(route) === 0;
return first ? (
{route.breadcrumbName}
) : (
{route.breadcrumbName}
);
}}
footerRender={() => defaultFooterDom}
// 这个方法就是自定义菜单
menuDataRender={()=>menuDataRender(menuData)}
rightContentRender={() => }
{...props}
{...settings}
>
{children}
dispatch({
type: 'settings/changeSetting',
payload: config,
})
}
/>
>
);
};
export default connect(({ global, settings }) => ({
collapsed: global.collapsed,
settings,
menuData: global.menuData, // 重点:自己再global.js 中添加一个方法fetchMenu 顶了一个菜单列表state:menuData
}))(BasicLayout);
二、再global.js中添加一个查询菜单列表的方法
import { queryMenu } from '@/services/user'; // 需要再这个文件中写个请求
const GlobalModel = {
namespace: 'global',
state: {
menuData:[], // 接受菜单列表
},
effects: {
// 获取菜单
*fetchMenu(_, { call, put }) {
const response = yield call(queryMenu);
yield put({
type: 'saveMenu',
payload: response,
});
},
},
reducers: {
// 菜单列表
saveMenu(state, { payload }){
return {
collapsed: false,
...state,
menuData: payload.meauList,
};
},
};
export default GlobalModel;