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

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

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

1、antd菜单新旧对比

老版本出现的情况

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',
  },

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

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

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

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

需要注意的是:

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

点击菜单进行页面跳转

就是右边一个,加一个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,这不就解决了我们需求吗

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);
}

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

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

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

导致问题

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

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

这种应该如何处理呢

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

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

处理问题

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

这个时候我们可以用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>

预览一下我们写法,报错

这是因为我们这个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,问题解决!

5、刷新时默认展开单个

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

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

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

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>

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

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

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

配置展开项openKeys的初始值

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} // 控制菜单的展开状态。这个参数用于控制当前哪些菜单项是展开的

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

相关推荐
啦啦右一1 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien1 小时前
Spring Boot常用注解
java·spring boot·后端
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王2 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发2 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
盛派网络小助手3 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
∝请叫*我简单先生3 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
zquwei4 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
dessler5 小时前
Docker-run命令详细讲解
linux·运维·后端·docker