菜單配置檔案
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 };