You need to enable JavaScript to run this app. 如何通过React Router的pathname同时高亮Antd两个独立组件的Menu.Item
优惠活动
大模型
产品
解决方案
定价
更多

如何通过React Router的pathname同时高亮Antd两个独立组件的Menu.Item

问题原因

你当前封装的Menu组件没有主动控制selectedKeys,Antd Menu默认的选中逻辑是匹配和当前路径完全相等的key,当访问/z/b时,主菜单的key为/z,和当前路径不完全匹配,因此不会高亮。另外不要使用defaultSelectedKeys,该属性仅在组件首次渲染时生效,路由切换后不会更新选中状态,必须用受控的selectedKeys属性。

解决方案

1. 改造封装的MenuItems组件

引入React Router的useLocation钩子获取当前路由路径,区分主菜单和二级菜单的匹配逻辑:主菜单做前缀匹配,只要当前路径以主路由path开头就标记为选中;二级菜单做完全路径匹配。

import { useLocation } from 'react-router-dom';
import { Menu } from 'antd';
import { Link } from 'react-router-dom';

const MenuItems = ({ routes, isMainMenu = false, theme, mode, ...items }) => {
  const { pathname } = useLocation();
  
  // 计算选中的菜单项key
  const getSelectedKeys = () => {
    if (isMainMenu) {
      // 主菜单前缀匹配,找到当前路径归属的父路由
      const matchedParentPath = routes.find(route => pathname.startsWith(route.path))?.path;
      return matchedParentPath ? [matchedParentPath] : [];
    }
    // 二级菜单完全匹配当前路径
    return [pathname];
  };

  const menuItems = routes.map(({ name, path }) => (
    <Menu.Item key={path}>
      <Link to={path}>{name}</Link>
    </Menu.Item>
  ));

  return (
    <Menu
      theme={theme}
      mode={mode}
      selectedKeys={getSelectedKeys()}
      {...items}
    >
      {menuItems}
    </Menu>
  );
};

2. 调整组件调用方式

主菜单调用时传入isMainMenu标识,开启前缀匹配逻辑:

{/* 根路径主菜单 */}
<MenuItems routes={mainRoutes} isMainMenu={true} />

{/* /z路径二级子菜单 */}
<MenuItems routes={subRoutes} />

3. 修正路由定义的语法错误

你现有subRoutes的path写错了,把正则格式改为字符串格式:

const subRoutes = [
  {
    path: '/z/a',
    name: 'z a',
    component: ...,
  },
  {
    path: '/z/b',
    name: 'z b',
    component: ...,
  },
  {
    path: '/z/c',
    name: 'z c',
    component: ...,
  }
];

扩展说明

如果后续有多层嵌套路由的需求,可以给每个路由配置项增加parentPath字段,匹配逻辑会更灵活,避免前缀匹配出现冲突的情况。

内容的提问来源于stack exchange,提问作者JavaScripter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 09:36:04