import { Layout, Menu, Icon } from 'antd'; import * as React from 'react'; const { SubMenu, Item: ItemMenu, ItemGroup } = Menu; const { Sider } = Layout; import { Iconfont } from '../Iconfont/Iconfont'; import { MenuMode } from 'antd/lib/menu'; import { SiderTheme } from 'antd/lib/layout/Sider'; import { PageComponent } from '../../types/index'; import { throttleWrap } from 'jad-tool' import { isString, isFunction } from 'jad-tool' type SiderProps = { width?: string | number; trigger?: string | React.ReactNode; collapsedWidth?: number; zeroWidthTriggerStyle?: object; [propName: string]: any; } type PropsKeyValue = { propPKeys: string, propKey: string, propName: string, propType: string, } type MenuDataProps = { key: string | number; name: string | number; pKeys?: (string | number)[]; icon?: any; path?: string; children?: MenuDataProps[]; type?: 'group' | 'menu'; // 默认是 'menu' —— 对应 SubMenu 和 ItemMenu keyValue?: PropsKeyValue, [propName: string]: any; } export class Sidebar extends React.Component any onClickMenuKey?: (key: string) => any onUpdateCollapsed?: (collapsed: boolean) => any }>> { keyValue = { propPKeys: 'pKeys', propKey: 'key', propName: 'name', propType: 'type', } constructor(props) { super(props); if (props['keyValue']) this.keyValue = { propPKeys: props['keyValue']['propPKeys'] || this.keyValue.propPKeys, propKey: props['keyValue']['propKey'] || this.keyValue.propKey, propName: props['keyValue']['propName'] || this.keyValue.propName, propType: props['keyValue']['propType'] || this.keyValue.propType, } } public dispatchResize = throttleWrap(300)(() => { //ie兼容 if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) { var evt = document.createEvent('UIEvents') as any; evt.initUIEvent('resize', true, false, window, 0); window.dispatchEvent(evt); } else { window.dispatchEvent(new Event('resize')); } }) onOpenChange(e) { const { onOpenMenuByKey = (key) => null, clickOpenWhoseAllChildren } = this.props; const { propPKeys, propKey } = this.keyValue; let keys = []; /* e.pKeys: string[];如1级菜单的pKeys.length为0,2级菜单的pKeys.length为1 (propPKeys 默认取值 pKeys) */ if (clickOpenWhoseAllChildren === (e[propPKeys].length + 1) && e.children) { /* 最底层可不查:children 不存在或[] */ const findChildrenOpenKeys = (data) => data.map(f => { if (f.children && f.children.length) { findChildrenOpenKeys(f.children); /* 最底层可不查不存(因为是openKeys):children 不存在或[] */ keys[keys.length] = f[propKey]; } }); findChildrenOpenKeys(e.children) } keys = [...e[propPKeys], ...keys, e[propKey]].filter(e => e); onOpenMenuByKey(keys) } onClickChange(key) { const { onClickMenuKey = (key) => null } = this.props onClickMenuKey(key) } onCollapse = (collapsed: boolean) => { const { onUpdateCollapsed = (collapsed) => null } = this.props onUpdateCollapsed(collapsed) this.dispatchResize() } recursionMenus = (menuItem: MenuDataProps) => { const { propKey, propName } = this.keyValue; if (!menuItem || !menuItem[propKey]) return const { propType } = this.keyValue; const menuType = menuItem[propType] || 'menu'; let menuIcon = menuItem.icon; let menuTitle = <> { menuIcon ? isFunction(menuIcon) ? menuIcon(menuItem) : : null } {menuItem[propName]} if (menuItem.children && menuItem.children.length) { switch (menuType) { case 'group': // ItemGroup return ( {menuItem.children.map((d) => this.recursionMenus(d))} ); case 'menu': // SubMenu default: return ( { this.onOpenChange(menuItem) }} > {menuItem.children.map((d) => this.recursionMenus(d))} ) } } else return ( // ItemMenu { this.onClickChange(menuItem[propKey]) }}> { (menuItem.outer && menuItem.outer.url) ? {menuTitle} : {menuTitle} } ) } renderMenus = (data: MenuDataProps[]) => { if (!data.length) return; return data.map((item) => this.recursionMenus(item)) } public render() { const { ifCollapsed, title, data = [], selectedKeys, openKeys, logo, siderProps = { width: 208, collapsedWidth: 50 } } = this.props; const menuProps = { theme: 'dark' as SiderTheme, mode: 'inline' as MenuMode, // inlineIndent:30, selectedKeys, openKeys, } if (ifCollapsed) delete menuProps.openKeys; const menu = ( {this.renderMenus(data)} ); return (
{ logo ? ( isString(logo) ? : logo ) : }

{ifCollapsed ? '' : title}

{menu}
); } }