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

相关推荐
轻口味17 分钟前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王1 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发1 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
高山我梦口香糖4 小时前
[react 3种方法] 获取ant组件ref用ts如何定义?
typescript·react
sunshine6414 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js