一级路由:
下面配置admin的二级路由
1.准备好数据
假设从后台得到的数据结构(根据不同角色返回的不同菜单数据)
const menuList = [
{
title: '首页',
icon: '<HomeOutlined />',
key: '/index',
},
{
title: '商品',
icon: '<ShopOutlined />',
key: '/productCate',
children:[
{
title: '品类管理',
icon: '<BarsOutlined />',
key: '/category',
},
{
title: '商品管理',
icon: '<CalendarOutlined />',
key: '/product',
}
]
}
{
title: '用户管理',
icon: '<UserOutlined />',
key: '/user',
},
{
title: '角色管理',
icon: '<SafetyCertificateOutlined />',
key: '/role',
},
]
2.利用antd提供的菜单menu渲染
import { Menu } from 'antd';
import {
HomeOutlined,
ShopOutlined,
BarsOutlined,
CalendarOutlined,
UserOutlined,
SafetyCertificateOutlined,
} from '@ant-design/icons';
const { SubMenu } = Menu;
class LeftMenu extends React.Component {
getMenuNodes(menuList){
menuList.map(item=>{
if(!item.children){
return (
<Menu.Item key={item.key} icon={item.icon}>
<Link to={item.key}>
{item.title}
</Link>
</Menu.Item>
)
}else{
return (
<SubMenu key={item.key} icon={item.icon} title={item.title}>
this.getMenuNodes(item.children)
</SubMenu>
)
}
})
}
render() {
return (
<div style={{ width: 256 }}>
<Menu
mode="inline"
theme="dark"
>
{this.getMenuNodes(this.menuList)}
</Menu>
</div>
);
}
}
export default class LeftMenu;
3.几个小细节
1.点击菜单跳转路由
<Link to={item.key}>
<Menu.Item key={item.key} icon={item.icon}>
<Link to={item.key}>
{item.title}
</Link>
</Menu.Item>
</Link>
2.动态生成菜单
getMenuNodes(menuList){
menuList.reduce((pre,item)=>{
if(!item.children){
pre.push(<Menu.Item key={item.key} icon={item.icon}>
<Link to={item.key}>
{item.title}
</Link>
</Menu.Item>)
}else{
pre.push(<SubMenu key={item.key} icon={item.icon} title={item.title}>
{this.getMenuNodes(item.children)}
</SubMenu>)
}
return pre;
},[])
}
3.自动选中当前菜单项
-
defaultSelectedKeys ,初始选中的菜单项 key 数组只能保证页面刚打开时默认展示的菜单项,但是页面刷新后,就失效了; -
而selectedKeys 当前展开的 SubMenu 菜单项 key 数组,可以是动态的;
那么怎么得到当前请求的路由路径呢?
我们知道,路由组件有三个属性,可以从里面的this.props.location.pathname 中得到,但是LeftMenu 只是Admin 组件的一个子组件,不是路由组件,要想让普通组件变成路由组件,拥有三大属性,react提供了一个方法,就是利用高阶组件withRouter
import {withRouter} from 'react-router-dom'
class LeftMenu extends React.Component{
render(){
const key = this.props.location.pathname;
return (
<Menu
mode="inline"
theme="dark"
selectedKeys={[key]}
>
{this.getMenuNodes(this.menuList)}
</Menu>
)
}
}
export default withRouter(<LeftMenu />)
4.自动打开当前子列表
defaultOpenKeys 初始展开的 SubMenu 菜单项 key 数组openKeys 当前展开的 SubMenu 菜单项 key 数组
<Menu
mode="inline"
theme="dark"
selectedKeys={[key]}
openKeys={[this.openKey]}
>
{this.getMenuNodes(this.menuList)}
</Menu>
getMenuNodes(menuList){
const path = this.props.location.pathname;
menuList.map(item=>{
if(!item.children){
return (
<Menu.Item key={item.key} icon={item.icon}>
<Link to={item.key}>
{item.title}
</Link>
</Menu.Item>
)
}else{
const cItem = item.children.find(cItem.key===path)
if(cItem){
this.openKey = item.key
}
return (
<SubMenu key={item.key} icon={item.icon} title={item.title}>
{this.getMenuNodes(item.children)}
</SubMenu>
)
}
})
}
所以我们需要在render() 最上面先调用getMenuNodes() ,但是放在render()函数中,每次更新的话,都要调用,所以最好放在componentWillMount 声明周期中调用:
componentWillMount(){
this.menuNodes = this.getMenuNodes(this.menuList)
}
render(){
return (
<SubMenu key={item.key} icon={item.icon} title={item.title}>
{this.menuNodes}
</SubMenu>
)
}
|