❤ React体系29-antd5左侧菜单最新版+Router(v6)实现(2024-06最新下)

❤ React体系29-antd5左侧菜单最新版+Router(v6)实现(2024-06最新下)

之前我们写了左侧菜单的实现,在最新的版本之中菜单的方式写法已经进行进行了更改,接下来我们看看新旧的不同和如何实现并且优化

1、antd菜单新旧对比

老版本出现的情况

image.png

Warning: [antd: Menu] children is deprecated. Please use items instead.

官方建议

Ant Design 版进行了版本更新。由于 Ant Design 的菜单组件(Menu)在下一个主要版本中将删除 children 属性,并更改为 items 属性。

旧版本写法

4.20及以前版本Menu的写法

 

js

复制代码

<Menu mode="inline" theme="dark" defaultSelectedKeys={['1']} style={{ height: '100%', borderRight: 0 }}> <Menu.Item icon={<HomeOutlined />} key="1"> 数据概览 </Menu.Item> <Menu.Item icon={<DiffOutlined />} key="2"> 内容管理 </Menu.Item> <Menu.Item icon={<EditOutlined />} key="3"> 发布文章 </Menu.Item> </Menu>

新版本写法

更新之后不再在Menus组件之中写子节点,改成了直接通过属性items配置类型的添加

 

js

复制代码

//结构方面 <Menu defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']} mode="inline" theme="dark" inlineCollapsed={collapsed} items={items} /> </> //配置item方面 const items = [ { key: '1', icon: <PieChartOutlined />, label: 'Option 1', }, { key: '2', icon: <DesktopOutlined />, label: 'Option 2', }, { key: 'sub1', label: 'Navigation One', icon: <MailOutlined />, children: [ { key: '5', label: 'Option 5', }, { key: '6', label: 'Option 6', }, { key: '7', label: 'Option 7', }, { key: '8', label: 'Option 8', }, ], }, ];

2、项目antd菜单最新写法(2024-06-05)

我们先看看新菜单里面的参数和作用

 

js

复制代码

- `defaultSelectedKeys`: 设置菜单的初始选中项。这个参数在初始化菜单时指定哪个菜单项是默认选中状态。 - `defaultOpenKeys`: 设置菜单的初始展开项。这个参数在初始化菜单时指定哪些菜单项是默认展开的。 - `selectedKeys`: 设置当前选中的菜单项。当用户点击菜单项时,这个参数用于更新当前选中的菜单项。 - `mode`: 设置菜单的模式,可以是 'vertical'(垂直)或 'horizontal'(水平)。 - `theme`: 设置菜单的主题,可以是 'light'(亮色)或 'dark'(暗色)。 - `onClick`: 指定菜单项点击事件的处理函数。当用户点击菜单项时,会调用这个函数进行相应的处理。 - `openKeys`: 控制菜单的展开状态。这个参数用于控制当前哪些菜单项是展开的。 - `onOpenChange`: 指定菜单展开/折叠事件的处理函数。当用户展开或折叠菜单项时,会调用这个函数进行相应的处理。 - `inlineCollapsed`: 设置菜单是否处于内联折叠状态。当菜单处于水平模式下,并且有子菜单时,可以通过这个参数控制菜单的折叠状态。 - `items`: 指定菜单项的配置信息。这个参数用于渲染菜单的具体内容。

上面这部分是官方给我们的写法,我们把他更改为自己的写法,这里大概是两种方式

第一种(重新组装为官方菜单)

第一种就是直接把我们数据组装一下,遍历赛进去,比较简单

 

js

复制代码

{ key: '1', icon: <PieChartOutlined />, label: 'Option 1', },

第二种 (采用-直接源路由改成官方参数方式)

我们是新项目,所以直接选择了源头更改,我直接把自己源路由改成了官方推荐的参数

image.png

然后引入和使用(这种处理真的是无脑且暴力)

 

js

复制代码

import routers,{adminRouter} from "@/router/index"; useEffect(() => { // setMenuList(items); setMenuList(adminRouter); }, []);

需要注意的是:

当我们没有内容的时候,进来不要写childern,像这种就是我写了空的children,或者自己进行一下筛选

image.png

点击菜单进行页面跳转

就是右边一个,加一个onClick事件

看一下官方的介绍

 

js

复制代码

onClick | 点击 MenuItem 调用此函数 | function({ item, key, keyPath, domEvent }) | | ------- | ----------------- | ------------------------------------------

然后我们尝试一下,先输出看看

 

js

复制代码

onClick={clickMenu} const clickMenu=({ item, key, keyPath, domEvent })=>{ console.log(item, key, keyPath, domEvent); }

这里我们可以看到,在我们这个props下包含了我们需要的所有信息,ok,这不就解决了我们需求吗

image.png

3、项目antd菜单点击跳转

 

js

复制代码

// 引入路由 import { Link, useLocation ,useNavigate} from 'react-router-dom'; let navigate=useNavigate(); // 进行跳转 const clickMenu=({ item, key, keyPath, domEvent })=>{ console.log(item, key, keyPath, domEvent); navigate(item.props.path); }

点击以后发现,我们的功能已经实现了!

image.png

回顾一下我们整个菜单的实现,其实也蛮简单的,就是左侧一个路由,然后右边其实相当于容器化的思想!

image.png

4、刷新不丢失菜单选中(刷新页面菜单保持用户之前的选中状态 )

导致问题

接下来我们针对菜单进行一部分优化,首先我们可以看到我们选择了角色以后,进行刷新,但是刷新以后发现菜单重新折叠并且还跑到了第一项

也就导致了这种情况:地址是角色的,展开的菜单确是首页的

image.png

这种应该如何处理呢

也就是我们需要实现用户进入界面默认展开所在区域二级菜单,加强用户体验

专业的说法就是刷新页面菜单保持用户之前的选中状态

处理问题

看看官方给我们提供的属性selectedKeys

image.png

这个时候我们可以用Menu的selectedKeys属性,官方的意思就是selectedKeys表示当前样式所在的选中项key

思路:那我们就是把获取当前的路径拿到key然后给到selectedKeys

拿到当前页面的路径

(类组件),使用this.props.location.pathname

(函数式组件) 使用hooks的useLocation().pathname

我们这里直接上函数组件写法

 

js

复制代码

import { Link, useLocation ,useNavigate} from 'react-router-dom';// 如果你使用React Router const location = useLocation(); const [selectedKey, setSelectedKey] = useState(''); //选中的菜单刷新不丢失 const currentPath = location.pathname; useEffect(() => { setMenuList(adminRouter); console.log(currentPath,'currentPath'); setSelectedKey(currentPath); }) <Menu defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']} selectedKeys={selectedKey} mode="inline" theme="dark" onClick={clickMenu} // openKeys={openKey} // inlineCollapsed={collapsed} items={menuList} > </Menu>

预览一下我们写法,报错 

image.png

这是因为我们这个selectedKeys类型是string[]

更改一下我们的写法,最终的大致就是这样子

 

js

复制代码

import React, { useState, useEffect } from 'react'; import { Menu } from 'antd'; // 假设你正在使用Ant Design import { useLocation } from 'react-router-dom'; // 如果你使用React Router function MyMenu({ menuList }) { const location = useLocation(); const [selectedKey, setSelectedKey] = useState<string[]>(['']); // 使用字符串数组来匹配路径 useEffect(() => { const currentPath = location.pathname; const matchedMenu = menuList.find(item => item.path === currentPath); // 根据路径查找匹配的菜单项 if (matchedMenu) { setSelectedKey([matchedMenu.key]); // 更新选中的菜单项为匹配的菜单键 } }, [location.pathname, menuList]); const clickMenu = (e) => { // 处理菜单点击事件 }; return ( <Menu defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']} selectedKeys={selectedKey} mode="inline" theme="dark" onClick={clickMenu} items={menuList} > {/* 渲染菜单项 */} </Menu> ); } export default MyMenu;

刷新以后ok,问题解决!

image.png

5、刷新时默认展开单个

当我们有多项菜单的时候可以发现,很多菜单都展开了,用户体验很不好,如何默认展开的菜单只有一项呢

如何达到这种效果呢 ,这个时候我们可以看看官方给我们提供的属性openKeys 和 onOpenChange

image.png

image.png

这个时候我们只需要添加一个展开项,同时在其他项点击的时候,

 

js

复制代码

import { Link, useLocation ,useNavigate} from 'react-router-dom';// 如果你使用React Router const [openKeys, setOpenKeys] = useState<string[]>(['']); const handleOpenChange = (keys: string[]) => { console.log(keys); setOpenKeys([keys[keys.length - 1]]); }; <Menu defaultSelectedKeys={['1']} defaultOpenKeys={['sub1']} selectedKeys={selectedKey} mode="inline" theme="dark" onClick={clickMenu} openKeys={openKeys} onOpenChange={handleOpenChange} items={menuList} > </Menu>

image.png

这个时候我们发现已经默认展开某一个了

6、刷新时默认展开选中项

我们刷新页面可以发现,页面的菜单又重新给这折叠了,根据我们正常的操作习惯,选中一个二级菜单节点的时候,刷新页面的时候应该保持用户之前的选中状态,并且二级菜单展开项应该默认展开。

配置展开项openKeys的初始值

image.png

 

js

复制代码

// 初始化菜单加载 const initMune=()=>{ let currentPath = location.pathname; //遍历路由表 adminRouter.map((itema) => { if(currentPath.indexOf(itema.path) === 0 ){ console.log(itema,'存在'); setOpenKeys([itema.key]); }else{ // console.log(itema,'不存在'); } }) } openKeys={openKeys} // 控制菜单的展开状态。这个参数用于控制当前哪些菜单项是展开的

这里我们菜单功能已经完结,散花!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值