SiderMenu.js 2.77 KB
Newer Older
jiang's avatar
jiang committed
1
import React, { PureComponent } from 'react';
jim's avatar
jim committed
2
import { Layout } from 'antd';
jiang's avatar
jiang committed
3 4
import { Link } from 'dva/router';
import styles from './index.less';
jim's avatar
jim committed
5
import BaseMeun, { getMeunMatcheys } from './BaseMeun';
6
import { urlToList } from '../utils/pathTools';
jiang's avatar
jiang committed
7

jim's avatar
jim committed
8
const { Sider } = Layout;
9

jiang's avatar
jiang committed
10 11 12
export default class SiderMenu extends PureComponent {
  constructor(props) {
    super(props);
ddcat1115's avatar
ddcat1115 committed
13
    this.menus = props.menuData;
14
    this.flatMenuKeys = this.getFlatMenuKeys(props.menuData);
jiang's avatar
jiang committed
15 16 17 18
    this.state = {
      openKeys: this.getDefaultCollapsedSubMenus(props),
    };
  }
19 20 21 22 23 24 25
  componentWillReceiveProps(nextProps) {
    if (nextProps.location.pathname !== this.props.location.pathname) {
      this.setState({
        openKeys: this.getDefaultCollapsedSubMenus(nextProps),
      });
    }
  }
陈帅's avatar
陈帅 committed
26 27 28 29 30
  /**
   * Recursively flatten the data
   * [{path:string},{path:string}] => {path,path2}
   * @param  menus
   */
jiang's avatar
jiang committed
31 32 33 34 35 36
  getFlatMenuKeys(menus) {
    let keys = [];
    menus.forEach((item) => {
      if (item.children) {
        keys = keys.concat(this.getFlatMenuKeys(item.children));
      }
37
      keys.push(item.path);
jiang's avatar
jiang committed
38 39 40
    });
    return keys;
  }
陈帅's avatar
陈帅 committed
41
  /**
jim's avatar
jim committed
42 43 44
   * Convert pathname to openKeys
   * /list/search/articles = > ['list','/list/search']
   * @param  props
45
   */
jim's avatar
jim committed
46 47 48
  getDefaultCollapsedSubMenus(props) {
    const { location: { pathname } } = props || this.props;
    return urlToList(pathname)
陈帅's avatar
陈帅 committed
49
      .map((item) => {
jim's avatar
jim committed
50
        return getMeunMatcheys(this.flatMenuKeys, item)[0];
陈帅's avatar
陈帅 committed
51
      })
52
      .filter(item => item);
ddcat1115's avatar
ddcat1115 committed
53
  }
jim's avatar
jim committed
54 55 56 57 58 59
  isMainMenu = (key) => {
    return this.menus.some(
      item =>
        key && (item.key === key || item.path === key),
    );
  }
ddcat1115's avatar
ddcat1115 committed
60 61 62
  handleOpenChange = (openKeys) => {
    const lastOpenKey = openKeys[openKeys.length - 1];
    const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1;
jiang's avatar
jiang committed
63
    this.setState({
ddcat1115's avatar
ddcat1115 committed
64
      openKeys: moreThanOne ? [lastOpenKey] : [...openKeys],
jiang's avatar
jiang committed
65
    });
66
  };
jiang's avatar
jiang committed
67
  render() {
jim's avatar
jim committed
68
    const { logo, collapsed, onCollapse, theme } = this.props;
69
    const { openKeys } = this.state;
jim's avatar
jim committed
70
    const defaultProps = collapsed ? {} : { openKeys };
jiang's avatar
jiang committed
71 72 73 74 75
    return (
      <Sider
        trigger={null}
        collapsible
        collapsed={collapsed}
76
        breakpoint="lg"
jiang's avatar
jiang committed
77 78
        onCollapse={onCollapse}
        width={256}
jim's avatar
jim committed
79
        className={`${styles.sider} ${theme === 'ligth' ? styles.ligth : ''}`}
jiang's avatar
jiang committed
80
      >
陈帅's avatar
陈帅 committed
81
        <div className={styles.logo} key="logo">
jiang's avatar
jiang committed
82 83 84 85 86
          <Link to="/">
            <img src={logo} alt="logo" />
            <h1>Ant Design Pro</h1>
          </Link>
        </div>
jim's avatar
jim committed
87 88
        <BaseMeun
          {...this.props}
陈帅's avatar
陈帅 committed
89
          key="Menu"
jiang's avatar
jiang committed
90
          mode="inline"
jim's avatar
jim committed
91
          handleOpenChange={this.handleOpenChange}
jiang's avatar
jiang committed
92 93
          onOpenChange={this.handleOpenChange}
          style={{ padding: '16px 0', width: '100%' }}
jim's avatar
jim committed
94
          {...defaultProps}
jim's avatar
jim committed
95
        />
jiang's avatar
jiang committed
96 97 98 99
      </Sider>
    );
  }
}