前言
随着侧边栏的东东越来越多..本来不考虑的三级菜单,也需要考虑进去了;
一开始都是手动map
去遍历对应的组件, 相关的的组id
这些也是简单的判断下children
就返回一个值;
有兴趣的瞧瞧
分析所需
路由规格统一,层级不定,允许子项带图标,自动生成对应的菜单栏数据
路由的写法是静态路由表的姿势;
const RouterTree = [ { key: 'g0', icon: 'dashboard', text: '数据分析', path: '/dashboard', children: [ { key: '1', text: '数据概览', path: '/dashboard/monitor', }, { key: '2', text: '日活月活', path: '/dashboard/dau', }, { key: '3', text: '用户留存', path: '/dashboard/retentio .... 此处省略N多重复规格的
思路
我的思路是直接递归,写成一个函数式组件.
风格用了antd
;
效果图
代码实现及用法
递归组件函数
性能耗时
基于我项目的,就二十来个左右,最深是三层,用console.time()
跑了下,性能还好
首次遍历树: 0.782958984375ms 第二次遍历树: 0.385009765625ms
里面的callback
主要是由外部传递一个处理函数,比如跳转的处理等等
// 递归侧边栏 sidebarTree = (RouterTree, callback) => { // 判断是否有效的数组,且长度大于0[再去递归才有意义] let isValidArr = value => value && Array.isArray(value); let isValidArrChild = value => value && value.children && Array.isArray(value.children) && value.children.length > 0; function recursive(Arr) { if (isValidArr(Arr)) { return Arr.map(ArrItem => { if (isValidArrChild(ArrItem)) { return ( <SubMenu key={ArrItem.key} title={ <div> {ArrItem.icon ? <Icon type={ArrItem.icon} theme="outlined" /> : null} <span>{ArrItem.text}</span> </div> } > {recursive(ArrItem.children)} </SubMenu> ); } return ( <Item key={ArrItem.key} onClick={() => callback(ArrItem)}> {ArrItem.icon ? <Icon type={ArrItem.icon} theme="outlined" /> : null} <span>{ArrItem.text}</span> </Item> ); }); } } return recursive(RouterTree); };
callback
(我这里是我的跳转函数)
// 路由跳转 gotoUrl = item => { const { history, location } = this.props; this.setState({ selectedKeys: [item.key], }); if (location.pathname === item.path) { return; } else { history.push(item.path); } };
用法
// 我自己维护的静态路由 import RouterTree, { groupKey, findKey } from './RouterTree'; <Sider breakpoint="lg" collapsed={collapsed} width="160" style={{ backgroundColor: `${theme ? '#001529' : '#fff'}` }} onCollapse={this.toggleCollapsed} > <Logo collapsed={collapsed} mode={mode} theme={theme} /> <Menu inlineIndent={12} subMenuOpenDelay={0.3} theme={theme ? 'dark' : 'light'} openKeys={openKeys} mode="inline" selectedKeys={selectedKeys} onOpenChange={this.onOpenChange} > {this.sidebarTree(RouterTree, this.gotoUrl)} </Menu> </Sider>