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

相关推荐
kingwebo'sZone1 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝3 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions3 小时前
2026年,微前端终于“死“了
前端·状态模式