| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import React, { PureComponent } from 'react';
- import { Layout } from 'antd';
- import pathToRegexp from 'path-to-regexp';
- import Link from 'umi/link';
- import styles from './index.less';
- import BaseMenu, { getMenuMatches } from './BaseMenu';
- import { urlToList } from '../_utils/pathTools';
- const { Sider } = Layout;
- /**
- * 获得菜单子节点
- * @memberof SiderMenu
- */
- const getDefaultCollapsedSubMenus = props => {
- const {
- location: { pathname },
- flatMenuKeys,
- } = props;
- return urlToList(pathname)
- .map(item => {
- return getMenuMatches(flatMenuKeys, item)[0];
- })
- .filter(item => item);
- };
- /**
- * Recursively flatten the data
- * [{path:string},{path:string}] => {path,path2}
- * @param menu
- */
- export const getFlatMenuKeys = menu =>
- menu.reduce((keys, item) => {
- keys.push(item.path);
- if (item.children) {
- return keys.concat(getFlatMenuKeys(item.children));
- }
- return keys;
- }, []);
- /**
- * Find all matched menu keys based on paths
- * @param flatMenuKeys: [/abc, /abc/:id, /abc/:id/info]
- * @param paths: [/abc, /abc/11, /abc/11/info]
- */
- export const getMenuMatchKeys = (flatMenuKeys, paths) =>
- paths.reduce(
- (matchKeys, path) =>
- matchKeys.concat(flatMenuKeys.filter(item => pathToRegexp(item).test(path))),
- []
- );
- export default class SiderMenu extends PureComponent {
- constructor(props) {
- super(props);
- this.flatMenuKeys = getFlatMenuKeys(props.menuData);
- this.state = {
- openKeys: getDefaultCollapsedSubMenus(props),
- };
- }
- static getDerivedStateFromProps(props, state) {
- const { pathname } = state;
- if (props.location.pathname !== pathname) {
- return {
- pathname: props.location.pathname,
- openKeys: getDefaultCollapsedSubMenus(props),
- };
- }
- return null;
- }
- isMainMenu = key => {
- const { menuData } = this.props;
- return menuData.some(item => {
- if (key) {
- return item.key === key || item.path === key;
- }
- return false;
- });
- };
- handleOpenChange = openKeys => {
- const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1;
- this.setState({
- openKeys: moreThanOne ? [openKeys.pop()] : [...openKeys],
- });
- };
- render() {
- const { logo, collapsed, onCollapse, fixSiderbar, theme } = this.props;
- const { openKeys } = this.state;
- const defaultProps = collapsed ? {} : { openKeys };
- return (
- <Sider
- trigger={null}
- collapsible
- collapsed={collapsed}
- breakpoint="lg"
- onCollapse={onCollapse}
- width={256}
- className={`${styles.sider} ${fixSiderbar ? styles.fixSiderbar : ''} ${
- theme === 'light' ? styles.light : ''
- }`}
- >
- <div className={styles.logo} key="logo" id="logo">
- <Link to="/">
- <img src={logo} alt="logo" />
- <h1>Ant Design Pro</h1>
- </Link>
- </div>
- <BaseMenu
- {...this.props}
- key="Menu"
- mode="inline"
- handleOpenChange={this.handleOpenChange}
- onOpenChange={this.handleOpenChange}
- style={{ padding: '16px 0', width: '100%' }}
- {...defaultProps}
- />
- </Sider>
- );
- }
- }
|