react+mobx实现侧边栏菜单

本文详细解析了一个票务平台的菜单配置文件,包括菜单ID、名称、路由及激活状态等关键信息,展示了如何通过React和MobX实现动态菜单加载与路由匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

菜单配置文件

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 };
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值