解决使用antd menu组件时保持选中菜单展开

64 阅读1分钟

在menu组件中添加openKeysonOpenChange

<Menu
  mode="inline"
  items={menuList}
  selectedKeys={selectedKeys}
  onClick={handleClickMenu}
  openKeys={stateOpenKeys}
  onOpenChange={onOpenChange}
  />

openkeys:当前展开的 SubMenu 菜单项 key 数组,

onOpenChange:SubMenu 展开/关闭的回调,

如果只设置openKeys不设置onOpenChange会导致其他菜单无法展开,所以一定要加onOpenChange事件。

编写一个工具函数,实现:根据子路径的key查找父路径的key

export const findParentKey = (
  menuItems: any,
  targetKey: string | number,
  parentKey: string | number | null = null
): string | number | null => {
  // 遍历当前层级的菜单项
  for (const item of menuItems) {
    // 将 item.key 转换为字符串进行比较,以处理数字 key 的情况
    if (String(item.key) === String(targetKey)) {
      // 如果当前项的 key 就是目标 key,返回其父级 key
      return parentKey;
    }
    // 如果当前项有子菜单,则在子菜单中递归查找
    if (item.children && item.children.length > 0) {
      const foundInChildren = findParentKey(item.children, targetKey, item.key);
      if (foundInChildren !== null) {
        return foundInChildren;
      }
    }
  }
  // 没有找到匹配的项
  return null;
};

因为组页面的路径拼接在路由地址里,可以根据这一特性在组件挂载的时候就设置openKeys的值,实现每次刷新都能根据当前页面展开对应菜单

const { pathname } = useLocation()
const [stateOpenKeys, setStateOpenKeys] = useState<string[]>([])
const initOpenKey = findParentKey(treeMenuList, pathname)
if (initOpenKey) {
  setStateOpenKeys([initOpenKey + ''])
}

这一步已经可以根据页面路径展开对应菜单了,但是无法点击其他菜单,现在添加onOpenChange事件来动态切换菜单

编写onOpenChange函数

    const onOpenChange = (key: any) => {
        if (key) {
            setStateOpenKeys(key)
        }
    }