| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- import React, { PureComponent } from 'react';
- import classNames from 'classnames';
- import { Menu, Icon } from 'antd';
- import Link from 'umi/link';
- import { urlToList } from '../_utils/pathTools';
- import { getMenuMatches } from './SiderMenuUtils';
- import { isUrl } from '@/utils/utils';
- import styles from './index.less';
- import IconFont from '@/components/IconFont';
- const { SubMenu } = Menu;
- // Allow menu.js config icon as string or ReactNode
- // icon: 'setting',
- // icon: 'icon-geren' #For Iconfont ,
- // icon: 'http://demo.com/icon.png',
- // icon: <Icon type="setting" />,
- const getIcon = icon => {
- if (typeof icon === 'string') {
- if (isUrl(icon)) {
- return <Icon component={() => <img src={icon} alt="icon" className={styles.icon} />} />;
- }
- if (icon.startsWith('icon-')) {
- return <IconFont type={icon} />;
- }
- return <Icon type={icon} />;
- }
- return icon;
- };
- export default class BaseMenu extends PureComponent {
- /**
- * 获得菜单子节点
- * @memberof SiderMenu
- */
- getNavMenuItems = menusData => {
- if (!menusData) {
- return [];
- }
- return menusData
- .filter(item => item.name && !item.hideInMenu)
- .map(item => this.getSubMenuOrItem(item))
- .filter(item => item);
- };
- // Get the currently selected menu
- getSelectedMenuKeys = pathname => {
- const { flatMenuKeys } = this.props;
- return urlToList(pathname).map(itemPath => getMenuMatches(flatMenuKeys, itemPath).pop());
- };
- /**
- * get SubMenu or Item
- */
- getSubMenuOrItem = item => {
- // doc: add hideChildrenInMenu
- if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
- const { name } = item;
- return (
- <SubMenu
- title={
- item.icon ? (
- <span>
- {getIcon(item.icon)}
- <span>{name}</span>
- </span>
- ) : (
- name
- )
- }
- key={item.path}
- >
- {this.getNavMenuItems(item.children)}
- </SubMenu>
- );
- }
- return <Menu.Item key={item.path}>{this.getMenuItemPath(item)}</Menu.Item>;
- };
- /**
- * 判断是否是http链接.返回 Link 或 a
- * Judge whether it is http link.return a or Link
- * @memberof SiderMenu
- */
- getMenuItemPath = item => {
- const { name } = item;
- const itemPath = this.conversionPath(item.path);
- const icon = getIcon(item.icon);
- const { target } = item;
- // Is it a http link
- if (/^https?:\/\//.test(itemPath)) {
- return (
- <a href={itemPath} target={target}>
- {icon}
- <span>{name}</span>
- </a>
- );
- }
- const { location, isMobile, onCollapse } = this.props;
- return (
- <Link
- to={itemPath}
- target={target}
- replace={itemPath === location.pathname}
- onClick={
- isMobile
- ? () => {
- onCollapse(true);
- }
- : undefined
- }
- >
- {icon}
- <span>{name}</span>
- </Link>
- );
- };
- conversionPath = path => {
- if (path && path.indexOf('http') === 0) {
- return path;
- }
- return `/${path || ''}`.replace(/\/+/g, '/');
- };
- getPopupContainer = (fixedHeader, layout) => {
- if (fixedHeader && layout === 'topmenu') {
- return this.wrap;
- }
- return document.body;
- };
- getRef = ref => {
- this.wrap = ref;
- };
- render() {
- const {
- openKeys,
- theme,
- mode,
- location: { pathname },
- className,
- collapsed,
- fixedHeader,
- layout,
- } = this.props;
- // if pathname can't match, use the nearest parent's key
- let selectedKeys = this.getSelectedMenuKeys(pathname);
- if (!selectedKeys.length && openKeys) {
- selectedKeys = [openKeys[openKeys.length - 1]];
- }
- let props = {};
- if (openKeys && !collapsed) {
- props = {
- openKeys: openKeys.length === 0 ? [...selectedKeys] : openKeys,
- };
- }
- const { handleOpenChange, style, menuData } = this.props;
- const cls = classNames(className, {
- 'top-nav-menu': mode === 'horizontal',
- });
- return (
- <>
- <Menu
- key="Menu"
- mode={mode}
- theme={theme}
- onOpenChange={handleOpenChange}
- selectedKeys={selectedKeys}
- style={style}
- className={cls}
- {...props}
- getPopupContainer={() => this.getPopupContainer(fixedHeader, layout)}
- >
- {this.getNavMenuItems(menuData)}
- </Menu>
- <div ref={this.getRef} />
- </>
- );
- }
- }
|