SiderMenu.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React, { PureComponent } from 'react';
  2. import { Layout } from 'antd';
  3. import classNames from 'classnames';
  4. import Link from 'umi/link';
  5. import styles from './index.less';
  6. import BaseMenu, { getMenuMatches } from './BaseMenu';
  7. import { urlToList } from '../_utils/pathTools';
  8. const { Sider } = Layout;
  9. /**
  10. * 获得菜单子节点
  11. * @memberof SiderMenu
  12. */
  13. const getDefaultCollapsedSubMenus = props => {
  14. const {
  15. location: { pathname },
  16. flatMenuKeys,
  17. } = props;
  18. return urlToList(pathname)
  19. .map(item => getMenuMatches(flatMenuKeys, item)[0])
  20. .filter(item => item);
  21. };
  22. export default class SiderMenu extends PureComponent {
  23. constructor(props) {
  24. super(props);
  25. this.state = {
  26. openKeys: getDefaultCollapsedSubMenus(props),
  27. };
  28. }
  29. static getDerivedStateFromProps(props, state) {
  30. const { pathname } = state;
  31. if (props.location.pathname !== pathname) {
  32. return {
  33. pathname: props.location.pathname,
  34. openKeys: getDefaultCollapsedSubMenus(props),
  35. };
  36. }
  37. return null;
  38. }
  39. isMainMenu = key => {
  40. const { menuData } = this.props;
  41. return menuData.some(item => {
  42. if (key) {
  43. return item.key === key || item.path === key;
  44. }
  45. return false;
  46. });
  47. };
  48. handleOpenChange = openKeys => {
  49. const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1;
  50. this.setState({
  51. openKeys: moreThanOne ? [openKeys.pop()] : [...openKeys],
  52. });
  53. };
  54. render() {
  55. const { logo, collapsed, onCollapse, fixSiderbar, theme } = this.props;
  56. const { openKeys } = this.state;
  57. const defaultProps = collapsed ? {} : { openKeys };
  58. const siderClassName = classNames(styles.sider, {
  59. [styles.fixSiderbar]: fixSiderbar,
  60. [styles.light]: theme === 'light',
  61. });
  62. return (
  63. <Sider
  64. trigger={null}
  65. collapsible
  66. collapsed={collapsed}
  67. breakpoint="lg"
  68. onCollapse={onCollapse}
  69. width={256}
  70. theme={theme}
  71. className={siderClassName}
  72. >
  73. <div className={styles.logo} id="logo">
  74. <Link to="/">
  75. <img src={logo} alt="logo" />
  76. <h1>Ant Design Pro</h1>
  77. </Link>
  78. </div>
  79. <BaseMenu
  80. {...this.props}
  81. mode="inline"
  82. handleOpenChange={this.handleOpenChange}
  83. style={{ padding: '16px 0', width: '100%' }}
  84. {...defaultProps}
  85. />
  86. </Sider>
  87. );
  88. }
  89. }