You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据选择切换Mantine双侧边栏的子菜单

解决Mantine双侧边栏主菜单切换对应子菜单的问题

问题根源

你的子菜单数据是无关联的扁平数组,没有和主菜单的active状态绑定,导致切换主菜单时子菜单不会跟着变化;同时主菜单切换时也没同步更新激活的子菜单状态。

解决方案

1. 重构子菜单数据结构

把扁平的子菜单改成和主菜单标签对应的分组结构,让每个主菜单都有专属子菜单:

const subLinksByMain = {
  Home: ['Dashboard', 'Releases', 'Account'],
  Dashboard: ['Orders', 'Clients', 'Databases'],
  Analytics: ['Pull Requests', 'Open Issues', 'Wiki pages'],
  Releases: ['Latest Builds', 'Archive', 'Changelog'],
  Account: ['Profile', 'Settings', 'Billing'],
  Security: ['Two-Factor Auth', 'Login History', 'Permissions'],
  Settings: ['General', 'Notifications', 'Integrations']
};

2. 优化状态与点击逻辑

  • 初始化时自动绑定默认主菜单的第一个子菜单
  • 点击主菜单时,同步更新激活的子菜单为对应分组的第一个选项

3. 调整子菜单渲染逻辑

只渲染当前激活主菜单对应的那组子菜单

修改后的完整代码

import { useState } from 'react';
import {
  IconCalendarStats,
  IconDeviceDesktopAnalytics,
  IconFingerprint,
  IconGauge,
  IconHome2,
  IconSettings,
  IconUser,
} from '@tabler/icons-react';
import { Title, Tooltip, UnstyledButton } from '@mantine/core';
import { MantineLogo } from '@mantinex/mantine-logo';
import classes from './DoubleNavbar.module.css';

const mainLinksMockdata = [
  { icon: IconHome2, label: 'Home' },
  { icon: IconGauge, label: 'Dashboard' },
  { icon: IconDeviceDesktopAnalytics, label: 'Analytics' },
  { icon: IconCalendarStats, label: 'Releases' },
  { icon: IconUser, label: 'Account' },
  { icon: IconFingerprint, label: 'Security' },
  { icon: IconSettings, label: 'Settings' },
];

// 按主菜单分组的子菜单数据
const subLinksByMain = {
  Home: ['Dashboard', 'Releases', 'Account'],
  Dashboard: ['Orders', 'Clients', 'Databases'],
  Analytics: ['Pull Requests', 'Open Issues', 'Wiki pages'],
  Releases: ['Latest Builds', 'Archive', 'Changelog'],
  Account: ['Profile', 'Settings', 'Billing'],
  Security: ['Two-Factor Auth', 'Login History', 'Permissions'],
  Settings: ['General', 'Notifications', 'Integrations']
};

export function DoubleNavbar() {
  // 初始化默认主菜单和对应子菜单
  const defaultActiveMain = 'Releases';
  const defaultActiveSub = subLinksByMain[defaultActiveMain][0];
  
  const [active, setActive] = useState(defaultActiveMain);
  const [activeLink, setActiveLink] = useState(defaultActiveSub);

  const handleMainLinkClick = (mainLabel) => {
    setActive(mainLabel);
    // 切换主菜单时自动激活对应子菜单的第一个选项
    setActiveLink(subLinksByMain[mainLabel][0]);
  };

  const mainLinks = mainLinksMockdata.map((link) => (
    <Tooltip
      label={link.label}
      position="right"
      withArrow
      transitionProps={{ duration: 0 }}
      key={link.label}
    >
      <UnstyledButton
        onClick={() => handleMainLinkClick(link.label)}
        className={classes.mainLink}
        data-active={link.label === active || undefined}
      >
        <link.icon size={22} stroke={1.5} />
      </UnstyledButton>
    </Tooltip>
  ));

  // 获取当前主菜单对应的子菜单
  const currentSubLinks = subLinksByMain[active];
  
  const links = currentSubLinks.map((link) => (
    <a
      className={classes.link}
      data-active={activeLink === link || undefined}
      href="#"
      onClick={(event) => {
        event.preventDefault();
        setActiveLink(link);
      }}
      key={link}
    >
      {link}
    </a>
  ));

  return (
    <nav className={classes.navbar}>
      <div className={classes.wrapper}>
        <div className={classes.aside}>
          <div className={classes.logo}>
            <MantineLogo type="mark" size={30} />
          </div>
          {mainLinks}
        </div>
        <div className={classes.main}>
          <Title order={4} className={classes.title}>
            {active}
          </Title>
          {links}
        </div>
      </div>
    </nav>
  );
}

关键改动说明

  • 数据结构重构:给主菜单和子菜单建立明确的关联关系
  • 点击逻辑优化:主菜单切换时自动同步子菜单激活状态,避免状态混乱
  • 渲染逻辑调整:只展示当前激活主菜单对应的子菜单,实现真正的联动效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:22:11