react 导航菜单选中项高亮 和 刷新保持打开状态栏

最近在写一个react demo 其中有个场景需求是 实现 导航菜单 路径匹配时选中项高亮 存在 打开子菜单项时 页面刷新 保持打开状态栏

代码实现颇有意思 记录一下

技术栈为 react-router-dom v6 版本 和 antd v5 版本

菜单项 主页

javascript 复制代码
import "./index.less";
import logo from "../../asstes/images/logo.png";
import {Link, useLocation, useNavigate} from "react-router-dom";
import { Menu } from "antd";
// 引入菜单配置项
import menuList from "../../config/menuConfig";
/*左侧导航组件
 */
/*左侧导航组件*/
function LeftNav() {
    // 引入子菜单

    const SubMenu = Menu.SubMenu;

    // 菜单栏跳转
    const navigate = useNavigate()
    const menuClick = (route) =>{
        // console.log(route)
        navigate(route.key)
    }
    // 获取当前页面路径
    const currentPath = useLocation()
    // 定一个函数来判断当前选中的路由是否需要打开,前提是有子路由  keys 组件数组
    const getOpenKey = (url_key,keys) => {
        let openKey = ''
        keys.forEach(item => {
            if(item.children){
                // 存在子路由
                item.children.forEach(
                    subItem =>{
                        if(url_key === subItem.key){
                            // 传入索引等于子路由索引  存储子路由索引
                            openKey = item.key
                        }
                        // 因为有嵌套列表所以需要采用递归调用
                        if(subItem.children){
                            getOpenKey(item.children)
                        }
                    }
                )
            }
        })
        // 返回存储的索引
        return openKey
    }
    // 渲染菜单项
    const menuNodes = (
        <Menu
            mode="inline"
            theme="dark"
            defaultSelectedKeys={["1"]}
            items={menuList}
            style={{ height: "100%", borderRight: 0 }}
            onClick={menuClick}
            selectedKeys={[currentPath.pathname]}
            defaultOpenKeys={[getOpenKey(currentPath.pathname,menuList)]}
        />
    );

    return (
        <div className="left-nav">
            <Link to={"/"} className="left-nav-header">
                <img src={logo} alt="logo" />
                <h3>云端后台</h3>
            </Link>
            {menuNodes}
        </div>
    );
}

export default LeftNav;

菜单数组

javascript 复制代码
import {
  AppstoreOutlined, AreaChartOutlined, BarChartOutlined,
  BarsOutlined,
  HomeOutlined, LineChartOutlined, PieChartOutlined,
  SafetyOutlined,
  ToolOutlined,
  UserOutlined
} from "@ant-design/icons";

const menuList = [
  {
    label: "首页", // 菜单标题名称
    key: "/home", // 对应的 path
    icon: <HomeOutlined />, // 图标名称
  },
  {
    label: "商品",
    key: "/products",
    icon: <AppstoreOutlined />,
    children: [
      // 子菜单列表
      {
        label: "品类管理",
        key: "/category",
        icon: <BarsOutlined />,
      },
      {
       label: "商品管理",
        key: "/product",
        icon: <ToolOutlined />,
      },
    ],
  },
  {
    label: "用户管理",
    key: "/user",
    icon: <UserOutlined />,
  },
  {
    label: "角色管理",
    key: "/role",
    icon: <SafetyOutlined />,
  },
  {
    label: "图形图表",
    key: "/charts",
    icon: <AreaChartOutlined />,
    children: [
      {
        label: "柱形图",
        key: "/charts/bar",
        icon: <BarChartOutlined />,
      },
      {
        label: "折线图",
        key: "/charts/line",
        icon: <LineChartOutlined />,
      },
      {
       label: "饼图",
        key: "/charts/pie",
        icon: <PieChartOutlined />,
      },
    ],
  },
];
export default menuList;

getOpenKey 通过传入当前路径索引 和 dom数组 遍历dom数组 存在子路由时 进行判断 数据源 当传入索引等于子路由索引 时 存入此时 打开的索引 openKey

最终返回 openKey 再赋值给 menu的 defaultOpenKeys 属性 保持页面打开时 仍存储打开栏状态

相关推荐
逐·風3 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫3 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦4 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享5 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
从兄6 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf7 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨7 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL7 小时前
npm入门教程1:npm简介
前端·npm·node.js