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 属性 保持页面打开时 仍存储打开栏状态

相关推荐
hpoenixf4 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特4 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷4 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian5 小时前
前端node常用配置
前端
华洛5 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq5 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A6 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常7 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端
小码哥_常7 小时前
从Groovy到KTS:Android Gradle脚本的华丽转身
前端
灵感__idea7 小时前
Hello 算法:复杂问题的应对策略
前端·javascript·算法