Skip to content

Menu

Menu 用于承载应用侧边栏、控制台导航和分组入口,支持嵌套展开、选中状态、受控状态、命令式控制与 sx 样式入口。

Basic

组合式 API 适合需要精细控制节点结构的场景。

Items

传递 items 可以快速生成菜单,适合由配置或后端数据驱动的导航。

useMenuRef

useMenuRef 用于创建 Menu 的命令式控制引用,避免每次手写 React.useRef<MenuRef>(null)

tsx
import { Menu, useMenuRef } from "@ldkj/web-ui";

export function Example() {
  const menuRef = useMenuRef();

  return (
    <Menu menuRef={menuRef}>
      <Menu.Item itemKey="home">首页</Menu.Item>
    </Menu>
  );
}

Controlled

selectedKeysopenKeys 可以完全受控,也可以通过 menuRef 做外部命令式控制。

Multiple

multipletrue 时,允许多个菜单项同时保持选中状态,适合偏好设置、订阅入口等多选场景。

Accordion

accordiontrue 时,同一父级下只保留一个子菜单展开,适合侧边栏层级较多、需要减少垂直占用的场景。

Indent

indent 控制每一层菜单的缩进像素,可根据侧边栏宽度和层级深度调整。

Item Gap

itemGap 控制菜单项之间的间距,也会同步作用于 Menu.Sub 头部和内部列表之间,保持层级展开后的视觉节奏一致。

SX + Colors

Menu 支持 sx,也可以通过 itemColors 批量调整菜单项的常见状态色。

常见场景

基础导航

用于页面跳转、层级定位或内容切换,帮助用户理解当前位置。

受控状态

当前项、展开项、页码或激活项需要和路由/查询参数同步时,使用受控模式。

可访问操作

导航项应保持可聚焦、可读,并在禁用或当前状态时给出明确语义。

Usage

组合模式:

tsx
import { Menu } from "@ldkj/web-ui";

export function Example() {
  return (
    <Menu defaultSelectedKeys={["overview"]} defaultOpenKeys={["workspace"]}>
      <Menu.Item itemKey="overview" icon="dashboard" href="/overview">
        总览
      </Menu.Item>
      <Menu.Sub itemKey="workspace" label="工作台" icon="folder">
        <Menu.Item itemKey="projects" icon="view_list">
          项目列表
        </Menu.Item>
        <Menu.Item itemKey="members" icon="group">
          成员管理
        </Menu.Item>
      </Menu.Sub>
    </Menu>
  );
}

配置模式:

tsx
import { Menu } from "@ldkj/web-ui";

export function ItemsExample() {
  return (
    <Menu
      defaultSelectedKeys={["release"]}
      defaultOpenKeys={["devops"]}
      items={[
        { key: "home", label: "首页", icon: "home", href: "/" },
        {
          key: "devops",
          label: "发布中心",
          icon: "publish",
          children: [
            { key: "pipeline", label: "流水线", icon: "dns" },
            { key: "release", label: "发布单", icon: "description" },
          ],
        },
      ]}
    />
  );
}

API

属性说明类型默认值
items快捷创建菜单的配置数组MenuItemConfig[]-
selectedKeys受控选中 keystring[]-
defaultSelectedKeys默认选中 keystring[][]
onSelectedKeysChange选中变化回调(keys, info) => void-
openKeys受控展开 keystring[]-
defaultOpenKeys默认展开 keystring[][]
onOpenKeysChange展开变化回调(keys, info) => void-
multiple是否允许多个 item 同时选中booleanfalse
accordion是否同层只保留一个子菜单展开booleanfalse
indent每一层缩进像素number18
itemGap菜单项之间的间距,数字自动转 pxnumber | string4
itemColors菜单项状态色MenuItemColors-
menuRef命令式控制引用React.Ref<MenuRef>-
listProps透传给内部 ulMenu.List props-
component自定义根节点元素React.ElementType"nav"
className追加类名string-
class历史类名别名string-
style内联样式React.CSSProperties-
sxCSS-in-JS 样式入口SxProps-
...rest继承 Box 的能力和原生属性透传BoxProps<T>-
属性说明类型默认值
itemKey菜单项唯一 keystring-
label菜单项内容;也可使用 childrenReact.ReactNode-
icon左侧图标名IconProps["name"]-
iconProps透传给 IconOmit<IconProps, "name">-
href链接地址;存在时默认渲染为 astring-
component自定义渲染元素React.ElementType"button""a"
disabled禁用菜单项booleanfalse
selected强制指定当前项选中态boolean-
unselectOnClick单选模式下再次点击是否取消选中booleanfalse
onSelect当前项被选中时触发(key: string) => void-
className/class/style/sx样式入口--
...rest原生属性透传React.ComponentPropsWithoutRef<T>-
属性说明类型默认值
itemKey子菜单唯一 keystring-
label子菜单标题React.ReactNode-
icon左侧图标名IconProps["name"]-
iconProps透传给 IconOmit<IconProps, "name">-
disabled禁用展开触发booleanfalse
children子菜单内容React.ReactNode-
className/class/style/sx样式入口--
...rest原生 li 属性透传React.ComponentPropsWithoutRef<"li">-
属性说明类型默认值
label分组标题React.ReactNode-
children分组内容React.ReactNode-
className/class/style/sx样式入口--
...rest原生 li 属性透传React.ComponentPropsWithoutRef<"li">-
属性说明类型默认值
key菜单 key;未传时回退到 href 或索引路径string-
label菜单文本或节点React.ReactNode-
icon左侧图标名IconProps["name"]-
href链接地址string-
disabled禁用当前项booleanfalse
children子节点配置MenuItemConfig[]-
type节点类型"item" | "sub" | "group"自动推断
itemProps透传给 Menu.ItemMenuItemProps-
subProps透传给 Menu.SubMenuSubProps-
groupProps透传给 Menu.GroupMenuGroupProps-
方法说明
select(key)选中指定项
unselect(key)取消指定项
open(key)展开指定子菜单
close(key)收起指定子菜单
toggleOpen(key)切换指定子菜单展开态
getSelectedKeys()获取当前选中 key
getOpenKeys()获取当前展开 key

行为规则 / 优先级

  • 导航组件应让当前项、禁用项和跳转目标保持一致。
  • classNameclass 用于追加类名;如同时传入原生 style,内联样式会按 React 规则覆盖同名 CSS。
  • 复杂内容优先通过组合能力传入,避免在组件内部硬编码业务文案。
  • Menu 的默认值应服务于最常见场景,特殊场景通过显式 props 覆盖。

Notes

  • Menu 不内置业务路由;需要路由库时,可通过 componentonClick 接入。
  • accordion 以同层子菜单为边界,不会影响其他层级的展开状态。
  • selectedKeys/openKeys 受控时,需要在对应 change 回调里同步外部状态。