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

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

相关推荐
cc蒲公英42 分钟前
javascript有哪些内置对象
java·前端·javascript
a努力。1 小时前
【基础数据篇】数据等价裁判:Comparer模式
java·后端
开心猴爷1 小时前
苹果App Store应用程序上架方式全面指南
后端
zhangwenwu的前端小站1 小时前
vue 对接 Dify 官方 SSE 流式响应
前端·javascript·vue.js
小飞Coding1 小时前
三种方式打 Java 可执行 JAR 包,你用对了吗?
后端
bcbnb1 小时前
没有 Mac,如何在 Windows 上架 iOS 应用?一套可落地的工程方案
后端
王林不想说话1 小时前
受控/非受控组件分析
前端·react.js·typescript
用户8356290780511 小时前
从一维到二维:用Spire.XLS轻松将Python列表导出到Excel
后端·python
哈哈哈笑什么1 小时前
SpringBoot 企业级接口加密【通用、可配置、解耦的组件】「开闭原则+模板方法+拦截器/中间件模式」
java·后端·安全