Sider菜单案例,把 md后缀修改为 zip,然后解压缩
Sider.md
使用 Sider
import Sider from '@layouts/Sider';const data = [{name: '仪表盘',icon: 'dashboard',path: '/dashboard', // before is 'dashboard'children: [{name: '分析页',path: '/dashboard/analysis', // before is 'analysis'children: [{name: '实时数据',path: '/dashboard/analysis/realtime', // before is 'realtime'},{name: '离线数据',path: '/dashboard/analysis/offline', // before is 'offline'},],},],},{name: '列表页',icon: 'list',path: '/list',},];function App() {const { pathname } = props.location;return (<Siderpathname={pathname}menuData={data}/>)}
Sider.jsx
import React, { useState, useEffect } from 'react';import { number, string, array, arrayOf, shape } from 'prop-types';import { Link } from 'dva/router';import { Menu } from 'antd';import { getSelectedKeys } from './utils';const { SubMenu, Item } = Menu;// submenu keys of first levelconst rootSubmenuKeys = ["/dashboard", "/list", "/"];Sider.propTypes = {width: number,pathname: string,menuData: arrayOf(shape({name: string,path: string,icon: string,children: array,})),};Sider.defaultProps = {menuData: [],width: 200,pathname: '/',};function Sider(props) {const { menuData, pathname, width } = props;// 初始值不能为空,否则切换路由,菜单会先收起,然后在展开;有闪烁问题const [state, setState ] = useState(getSelectedKeys({menuData,pathname}));useEffect(update, [pathname, menuData]);function update() {const newKeys = getSelectedKeys({menuData,pathname});setState(newKeys)}function onOpenChange(keys) {// setState(prevState => ({...prevState, openKeys}));let openKeys = keys// 如果没找到const latestOpenKey = keys.find((key) => !state.openKeys.includes(key));if (!rootSubmenuKeys.includes(latestOpenKey)) {openKeys = keys;} else {openKeys = latestOpenKey ? [latestOpenKey] : []}setState(prevState => ({...prevState, openKeys}));}function renderMenu(data) {return data.map((item) => {const { children, path, name } = item;if (children && children.length) {return (<SubMenukey={path}title={<span>{name}</span>}>{renderMenu(children)}</SubMenu>);}return (<Item key={path}><Link to={path} href={path}><span>{name}</span></Link></Item>);})}const { openKeys, selectedKeys } = state;const MenuProps = {mode:'inline',theme:'dark',// inlineCollapsed: true, // 收起菜单openKeys, // 当前展开的 SubMenu菜单项selectedKeys, // 选中的菜单项 key 数组onOpenChange,}console.log('state', state)return (<div style={{ width }}><Menu {...MenuProps}>{renderMenu(menuData)}</Menu></div>);}export default Sider;
菜单闪烁问题
openKeys初始值不能为空数组
否则切换路由,菜单会先收起,然后在展开;有闪烁问题
const [state, setState] = useState({openKeys: [],selectedKeys: [],});useEffect(update, [pathname, menuData]);function update() {const pathArray = getFlatMenuKeys(menuData);const selectedKeys = getMenuMatchKeys(pathArray, urlToList(pathname));setState({openKeys: selectedKeys,selectedKeys,});}
