菜单配置文件
container > sideMenu > configMenu.js
/**
* @description 左侧菜单配置
* @param(leafMenuModels) 子节点菜单
* @param(active) boolean 当前菜单是否被选中
* @param(id) string 菜单ID,唯一,不能重复
* @param(name) string 菜单名称
* @param(router) 菜单对应的路由
* @param(activeRouter) 当前菜单下包含的路由
*/
module.exports = {
id: "0",
name: "票务平台",
leafMenuModels: [
{
id: "1",
active: true,
name: "平台首页",
router: "/",
activeRouter: ["/", "/ticket/create/:key/:conferenceId"]
},
{
id: "2",
active: true,
name: "创建会场",
router: "/meeting/create",
activeRouter: ["/meeting/create", "/meeting/create/:id"]
},
{
id: "3",
active: true,
name: "数据查看",
router: "/data/view",
activeRouter: ["/data/view", "/data/view/:id"]
},
{
id: "4",
active: true,
name: "订单列表",
router: "/order",
activeRouter: ["/order", "/order/:searchParams", "/orderDetail/:orderId"]
}
]
};
菜单主文件
container > sideMenu > index.js
import React, { Component } from "react";
import { Link, NavLink, withRouter } from "react-router-dom";
import { toJS } from "mobx";
import { inject, observer } from "mobx-react";
import { Menu, Icon, Button } from "antd";
const SubMenu = Menu.SubMenu;
@inject("MenuStore")
@observer
class SideMenu extends Component {
componentDidMount() {
// 设置menu
this.props.MenuStore.initMenu(this.props);
}
// react路由发生变化时会触发该函数
componentWillReceiveProps(nextProps) {
// 设置menu
this.props.MenuStore.initMenu(nextProps);
}
// 菜单切换时触发
toSkip = path => {
this.props.history.push(path);
};
render() {
const { menus, selectedKeys } = this.props.MenuStore;
return (
<div className="container-side-menu">
<Menu selectedKeys={toJS(selectedKeys)} mode="inline" theme="dark">
{menus.map(item => {
return (
<Menu.Item
key={item.id}
onClick={this.toSkip.bind(this, item.router)}
>
<span>{item.name}</span>
</Menu.Item>
);
})}
</Menu>
</div>
);
}
}
export default withRouter(SideMenu);
菜单store文件
stores > MenuStore.js :
import { action, observable } from "mobx";
import menuConfig from "../containers/SideMenu/configMenu";
// 方法在下面?
import { isActiveMenu } from "../utils/menu";
const uuid = require("uuid/v1");
class MenuStore {
@observable menus = [];
@observable selectedKeys = []; // 当前选中的菜单
// 初始化进来的时候,判断路由,设置菜单的active属性以及被选中的key的集合
@action
initMenu(props) {
let { leafMenuModels: menus } = menuConfig;
let pathname = props.location.pathname;
for (let index = 0; index < menus.length; index++) {
let menu = menus[index];
if (isActiveMenu(menu, pathname) === true) {
this.selectedKeys = [menu.id];
}
menu.active = isActiveMenu(menu, pathname);
}
this.menus = menus;
}
}
const menuStore = new MenuStore();
export default menuStore;
根据路由判断菜单是否应该被选中
utils > menu.js :
import { forEach } from "lodash";
// 将路径字符串转换为正则表达式 需要使用**安装**
import pathToRegexp from "path-to-regexp";
// 根据路由判断菜单是否应该被选中
function isActiveMenu(menu, pathname) {
let router = menu.activeRouter || null,
active = false;
if (router) {
if (Array.isArray(router) && router.length) {
forEach(router, item => {
// item: /orderDetail/:orderId ; pathname: /orderDetail/1
if (!active && pathToRegexp(item).test(pathname)) {
active = true;
}
});
}
if (
typeof router === "string" &&
!active &&
pathToRegexp(router).test(pathname)
) {
active = true;
}
}
return active;
}
export { isActiveMenu };