首页 > 编程知识 正文

农耕记湘菜,antd样式覆盖

时间:2023-05-05 08:32:36 阅读:113908 作者:2312

本文使用的知识: react相关和antd等。

有关antd的Layout.Sider的使用说明,请转到这里。 https://ant.design/components/layout-cn /

本文采用了“路由与菜单分开管理”的理念来实现sidebar。 这样的好处是:

所有路由都不需要在sidebar上展示; 避免在根中添加控制菜单属性,降低根与菜单的结合度,简化根的维护。 导入{ menu,Layout } from 'antd '; 导入{ database outlined,UnorderedListOutlined,HistoryOutlined,TeamOutlined,DeleteOutlined,} from ' @ ant-design in 导入{链接}从' react-router-DOM '; 导入工具包自' js-cookie '; import './index.less ' const { submenu }=menu; const { sider }=layoutconstsidebar=(props )={ const { globalCurrentZoo,location,}=props; const superAdmin=() return )、) kkdhmg ) }constusername=cookies.get ) username ); const isSuperAdmin=superAdmin ().includes(username ); const { pathname }=location; const [collapsed,setcollapsed]=usestate(false; const [zoo,setZoo]=useState (' '; let selectedKeys=[],openKeys=[]; useEffect ()={ globalcurrentzoosetzoo (globalcurrentzoo.name ) },[globalCurrentZoo]; const menuList=[{ title: '鱼类',key: '/animal/:zoo/fish ',icon :数据库大纲/,path 3360 `/AAA key : '/animal/: zoo/birds/: type/list ',icon 3360 unorderedlistoutlined/icon 3360 key : '/animal/3: path : `/animal/$ { zoo }/birds/chicken/list `,rule { title: '鸭子',key : '/animal/: zoo/biriral path : `/animal/$ { zoo }/birds/duck//},{ title: '两栖动物',key : '/animal/: zoo/amphibibians ', { title :’爬行动物’,key :’/animal/: zoo/reptiles’,icon: TeamOutlined /,path3360`/animal/animal $/常数管理器menus=() issuperadmin? (menulist.push(title: (哺乳动物(,key: )/animal/:zoo/mammals )、icon: DeleteOutlined /,submenus33666 )

"猫", key: "/animal/:zoo/mammals/cat", path: `/animal/${zoo}/mammals/cat`, rule: //animal/[sS]+/mammals/cat/?$/, },{ title: "狗", key: "/animal/:zoo/mammals/dog", path: `/animal/${zoo}/mammals/dog`, rule: //animal/[sS]+/mammals/dog/?$/, }] } ) ) : ("")} } let flag = false; const matchPath = (arr, path, defaultRes={}) => { let res = { key: null, parentKey: null, ...defaultRes, } for (let i = 0; i < arr.length; i++) { const item = arr[i]; if(flag) break; if(item.rule){ const rule = item.rule const matched = rule.test(path) if (!matched) { // 当遍历到子菜单的最后一项时将parentKey置为null if(i >= arr.length - 1){ res = { ...res, parentKey: null } } continue; }else{ let key = item.key if(res.parentKey){ // 多级菜单 res = { ...res, key } }else{ // 一级菜单 res = { ...res, key, parentKey: null } } flag = true; break; } } if (item.subMenus && Array.isArray(item.subMenus)) { const parentKey = item.key; // 递归 const subMenusResult = matchPath(item.subMenus, path, { parentKey }) res = { ...res, ...subMenusResult } } } return res; } managerMenus(); const { key, parentKey } = matchPath(menuList, pathname); key && (selectedKeys = [key]); parentKey && (openKeys = [parentKey]); const onCollapse = collapsed => { setCollapsed(collapsed); }; return ( <div className="sidebar-wrap" style={{width: collapsed ? "80px" : "200px"}}> <Sider className="sidebar" collapsible collapsed={collapsed} theme="light" onCollapse={onCollapse} style={{position: 'absolute'}} > <Menu className="sidebar-menu" mode="inline" defaultSelectedKeys={selectedKeys} defaultOpenKeys={openKeys} > {menuList.map((item, idx) => { return ( <React.Fragment key={idx}> {item.subMenus ? ( <SubMenu key={item.key} icon={item.icon} title={item.title} > {item.subMenus.map((subItem, subIdx) => { return ( <Menu.Item key={subItem.key}> <Link to={subItem.path}>{subItem.title}</Link> </Menu.Item> ) })} </SubMenu> ) : ( <Menu.Item key={item.key} icon={item.icon}> <Link to={item.path}>{item.title}</Link> </Menu.Item> )} </React.Fragment> ) })} </Menu> </Sider> </div> );}export default Sidebar;

上述代码完全实现了 sidebar,美中不足是:在封装 matchPath 方法时,需要全局声明一个 flag 变量来控制菜单。这会造成该方法与该组件的强耦合,不方便共用。

于是我对 matchPath 方法做了优化:

const matchPath = (arr, path, defaultRes={}) => { let res = { key: null, parentKey: null, ...defaultRes, } for (let i = 0; i < arr.length; i++) { const item = arr[i]; if(res.parentKey) break; if(item.rule){ const rule = item.rule const matched = rule.test(path) if (!matched) { // 当遍历到子菜单的最后一项时将p置为null if(i >= arr.length - 1){ res = { ...res, p: null } } continue; }else{ let key = item.key if(res.p){ // 多级菜单 res = { ...res, key, parentKey:res.p } }else{ // 一级菜单 res = { ...res, key, parentKey:key } } break; } } if (item.subMenus && Array.isArray(item.subMenus)) { const p = item.key; const subMenusResult = matchPath(item.subMenus, path, {p}) res = { ...res, ...subMenusResult } } } return res; }

优化后,实现了无需全局声明一个 flag 变量来控制菜单,可是这样会带来一个负面效果:虽然最终的 selectedKeys 和 openKeys 的值是对的,但是 Menu 拿到正确的 openKeys 后,defaultOpenKeys 却是失效的,不知为何,若有幸被大佬看到,求支点迷津(o^^o)。

还有一种优化思路和大家交流一下:就是在写一个函数,在该函数中调用 matchPath 函数,调用之前声明一个变量 flag,初始值是 false。

 

左侧菜单,滚动条实现:

给整个菜单的容器加上以下样式:

.sidebar { height: 100%; max-height: 100vh; overflow: scroll;}

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。

  • 相关阅读