返回目录
组件详情入口
导航
@vean/ui
SMenubar

Menubar

Menubar 属于 导航 分类。建议先看演示与用法,再对照 API 表格完成接入和样式调整。

先用快捷跳转面板找到概述、用法、演示和 API,再往下细读完整文档内容。

快速跳转

同分类组件

如果你在同一类交互里做组合,这些组件通常会一起出现。

菜单栏

概述

Menubar 用于构建常驻应用顶部的横向菜单栏:顶层为一组可横向漫游焦点的触发器,点击或悬停展开下拉菜单,支持任意层级嵌套子菜单与完整键盘导航。

SMenubar 是数据驱动的聚合组件:传入 items 数组即可渲染完整的 role="menubar" 结构、触发器、下拉内容与嵌套子菜单。顶层项既可以是"展开下拉"的触发器,也可以是直接跳转的链接(提供 href / to 即可)。逻辑与无障碍语义由 Aria MenubarCompact 承载,样式通过 scv() 配方注入。

SMenubar 把全部结构组合委托给 Aria MenubarCompact。无样式的数据驱动用法可导入 @vean/aria/menubar;下拉菜单部分复用 @vean/aria/menu 的 MenuOptionsCompact。

功能特性

  • 数据驱动组合 — 传 items(MenuOptionData)即可渲染菜单栏;顶层项通过 children 声明下拉菜单,子项支持 label / icon / shortcut / disabled / separator / href / to,子项可继续嵌套。
  • 横向 Roving Focus — 根节点保持单一 Tab 停止点,ArrowLeft / ArrowRight 在触发器间移动焦点,loop 开启时首尾循环;禁用触发器被移出焦点顺序。
  • 完整键盘导航 — Enter / Space 切换菜单、ArrowDown 打开;菜单内方向键漫游条目、ArrowRight / ArrowLeft 切换相邻顶层菜单;Escape 关闭并归还焦点。
  • 悬停 / 指针切换 — 菜单打开后悬停其他触发器即切换打开的菜单;悬停链接型触发器会收起菜单并聚焦该链接。
  • 点击 / 悬停触发模式 — trigger 支持 click(默认)与 hover:click 模式点击展开菜单,菜单打开后悬停其他触发器仍可切换;hover 模式悬停即展开(可用 delayDuration / skipDelayDuration 控制延迟与连开窗口),并带指针宽限区,可在菜单栏与内容之间平滑移动而不误关。
  • 溢出折叠 — collapsible 开启后,当菜单栏内容超出容器宽度时,末尾的顶层项自动合并进一个"更多"菜单,始终保证内容宽度不超过容器宽度;可用 moreLabel / moreIcon / moreProps / more-trigger 插槽定制。
  • 链接型顶层项 — 提供 href / to 的顶层项渲染为链接(不展开下拉),与导航菜单模式一致;链接保留 target / external / disabled 语义。
  • 嵌套子菜单 — 子项通过 MenuSub 组合渲染任意层级子菜单,支持方向键进入 / 退出、指针宽限区防抖(100ms 打开延迟)。
  • 受控 / 非受控 — 提供 modelValue 时打开的菜单跟随 prop 并触发 update:modelValue;否则使用 defaultValue 做非受控初始值。
  • 逐项与整体禁用 — item.disabled 使单个顶层项完全惰性(aria-disabled + 移出 Tab 顺序 + 阻断交互);紧凑组件级 disabled 一次禁用全部触发器(含链接型)。
  • 隐藏项 — item.hidden 移除整个顶层项及其下拉菜单;隐藏项在溢出计算之前就被过滤,因此 collapsible 只统计可见触发器。子项标记 hidden 则从其下拉菜单中移除。
  • 双向方向 — dir 支持 LTR / RTL,方向键与子菜单滑入方向均按逻辑方向处理;portalProps 控制内容是否传送到 body。
  • 六种尺寸 — size(xs…2xl)变体覆盖根节点与触发器的间距、内边距与字号。
  • 菜单槽位透传 — item-leading / item-trailing / trigger / item-link-icon 等插槽透传至菜单层,可按项定制内容;ui prop 覆盖根节点与触发器槽位。
  • Aria 组合 — MenubarRoot / MenubarMenu / MenubarTrigger / MenubarContent / MenubarSubTrigger / MenubarSubContent 及 Compact 均可从 @vean/aria/menubar 导出,菜单基础件复用 @vean/aria/menu。

用法

演示

基础

受控

Active menu:

TriggerMode

Triggerclickhover

Overflow

Collapsible

API

Aria 层

21

Menubar<T>

36 属性10 事件7 插槽
属性
属性名类型默认值描述
class
ClassValue
—
菜单栏根类
size
ThemeSize
—
组件的视觉尺寸。
ui
Partial<MenubarUi>
—
该组件的按槽类重写。
indicatorPosition
AlignSide
—
指示符位置。
disabled
boolean
—
该组件是否已禁用。
placement
Placement
—
位置。
showArrow
boolean
—
是否显示箭头。
triggerProps
MenubarTriggerProps
—
转发给触发元素的属性。
collapsible
boolean
—
当 `true` 时,如果菜单栏内容宽度超过其容器, 末尾的项目将折叠为一个“更多”下拉菜单,以确保内容始终 能完全显示在容器内。
moreLabel
string
undefined
当 `collapsible` 时,末尾“更多”触发器的标签。
moreIcon
IconValue
—
当 `collapsible` 时,末尾“更多”触发器的图标。
moreProps
MenubarTriggerProps
—
属性将转发至末尾的“more”触发器。
portalProps
MenuPortalProps
—
转发给 portal 元素的属性。
contentProps
MenubarContentProps
—
转发给内容元素的属性。
popupProps
MenuPopupProps
—
转发给弹出窗口元素的属性。
arrowProps
MenuArrowProps
—
转发给箭头元素的属性。
modelValue
T
—
要打开的菜单的受控值。可作为 `v-model` 使用。
defaultValue
T
—
初始渲染时应打开的菜单值。
dir
Direction
—
如适用,请保留菜单栏的阅读方向。
loop
boolean
—
当值为 `true` 时,键盘导航会在最后一次触发点与第一个触发点之间循环。
trigger
MenubarTriggerType
'click'
菜单栏的触发类型。 - `click`:点击触发器时将打开菜单(将鼠标悬停在 已打开的菜单栏上仍可在菜单之间切换)。 - `hover`:将鼠标悬停在触发器上时将打开菜单。
delayDuration
number
150
从指针进入触发器到菜单在悬停模式下 打开所花费的时间。
skipDelayDuration
number
300
用户在触发延迟之前,还有多少时间可以输入另一个触发条件。 延迟。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
items
MenuOptionData<T>[]
—
由该组件渲染的项。
selectedValue
T
—
菜单中的选定值。
itemProps
MenuItemProps
—
转发给 item 元素的属性。
linkProps
LinkExtraProps
—
传递给 link 元素的属性。
subProps
MenuSubProps
—
转发给子元素的属性。
groupProps
MenuGroupProps
—
转发给 group 元素的属性。
groupLabelProps
MenuGroupLabelProps
—
转发至组标签元素的属性。
shortcutProps
MenuShortcutProps
—
转发给快捷方式元素的属性。
separatorProps
MenuSeparatorProps
—
转发给分隔符元素的属性。
subTriggerProps
MenuSubTriggerProps
—
转发给子触发器元素的属性。
subContentProps
MenuSubContentProps
—
转发至子内容元素的属性。
事件
事件名参数描述
update:modelValue
T
当模型值发生变化时触发。
escapeKeyDown
KeyboardEvent
当 Esc 键被按下时触发的事件处理程序。可被阻止。
pointerDownOutside
PointerDownOutsideEvent
当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。
focusOutside
FocusOutsideEvent
当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown` 事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。
openAutoFocus
Event
在打开页面时自动聚焦时触发的事件处理程序。可被阻止。
closeAutoFocus
Event
在关闭时自动聚焦时触发的事件处理程序。可被阻止。
entryFocus
Event
在条目获得焦点时触发。
update:open
boolean
当对话框的打开状态发生变化时调用的事件处理程序。
select
MenuOptionData<T>, event: Event
在发生 select 事件时触发。
插槽
插槽名参数描述
item
{ item: MenuOptionData<T>; isTrigger?: boolean; }
项插槽的自定义内容。
item-leading
{ item: MenuOptionData<T>; }
用于项目引导槽位的自定义内容。
item-trailing
{ item: MenuOptionData<T>; }
用于项目尾部槽位的自定义内容。
item-trigger-icon
{ item: MenuOptionData<T>; }
项目触发图标槽位的自定义内容。
item-link-icon
{ item: MenuOptionData<T>; }
项目链接图标槽位的自定义内容。
trigger
((data: { item: MenuOptionData<T>; }) => any)
触发器插槽的自定义内容。 可选:当消费者未提供内容时,`MenubarCompact` 会渲染完整的默认触发器内容(图标、 标签、链接图标、尾部插槽)。
more-trigger
—
当 `collapsible` 时,为末尾的“更多”触发器提供自定义内容。

MenubarArrow

MenubarCheckboxGroup

MenubarCheckboxItem

MenubarCompact<T>

32 属性10 事件7 插槽
属性
属性名类型默认值描述
disabled
boolean
—
该组件是否已禁用。
placement
Placement
—
位置。
showArrow
boolean
—
是否显示箭头。
triggerProps
MenubarTriggerProps
—
转发给触发元素的属性。
collapsible
boolean
—
当 `true` 时,如果菜单栏内容宽度超过其容器, 末尾的项目将折叠为一个“更多”下拉菜单,以确保内容始终 能完全显示在容器内。
moreLabel
string
undefined
当 `collapsible` 时,末尾“更多”触发器的标签。
moreIcon
IconValue
—
当 `collapsible` 时,末尾“更多”触发器的图标。
moreProps
MenubarTriggerProps
—
属性将转发至末尾的“more”触发器。
portalProps
MenuPortalProps
—
转发给 portal 元素的属性。
contentProps
MenubarContentProps
—
转发给内容元素的属性。
popupProps
MenuPopupProps
—
转发给弹出窗口元素的属性。
arrowProps
MenuArrowProps
—
转发给箭头元素的属性。
modelValue
T
—
要打开的菜单的受控值。可作为 `v-model` 使用。
defaultValue
T
—
初始渲染时应打开的菜单值。
dir
Direction
—
如适用,请保留菜单栏的阅读方向。
loop
boolean
—
当值为 `true` 时,键盘导航会在最后一次触发点与第一个触发点之间循环。
trigger
MenubarTriggerType
'click'
菜单栏的触发类型。 - `click`:点击触发器时将打开菜单(将鼠标悬停在 已打开的菜单栏上仍可在菜单之间切换)。 - `hover`:将鼠标悬停在触发器上时将打开菜单。
delayDuration
number
150
从指针进入触发器到菜单在悬停模式下 打开所花费的时间。
skipDelayDuration
number
300
用户在触发延迟之前,还有多少时间可以输入另一个触发条件。 延迟。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
items
MenuOptionData<T>[]
—
由该组件渲染的项。
selectedValue
T
—
菜单中的选定值。
itemProps
MenuItemProps
—
转发给 item 元素的属性。
linkProps
LinkExtraProps
—
传递给 link 元素的属性。
subProps
MenuSubProps
—
转发给子元素的属性。
groupProps
MenuGroupProps
—
转发给 group 元素的属性。
groupLabelProps
MenuGroupLabelProps
—
转发至组标签元素的属性。
shortcutProps
MenuShortcutProps
—
转发给快捷方式元素的属性。
separatorProps
MenuSeparatorProps
—
转发给分隔符元素的属性。
subTriggerProps
MenuSubTriggerProps
—
转发给子触发器元素的属性。
subContentProps
MenuSubContentProps
—
转发至子内容元素的属性。
事件
事件名参数描述
update:modelValue
T
当模型值发生变化时触发。
escapeKeyDown
KeyboardEvent
当 Esc 键被按下时触发的事件处理程序。可被阻止。
pointerDownOutside
PointerDownOutsideEvent
当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。
focusOutside
FocusOutsideEvent
当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown` 事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。
openAutoFocus
Event
在打开页面时自动聚焦时触发的事件处理程序。可被阻止。
closeAutoFocus
Event
在关闭时自动聚焦时触发的事件处理程序。可被阻止。
entryFocus
Event
在条目获得焦点时触发。
update:open
boolean
当对话框的打开状态发生变化时调用的事件处理程序。
select
MenuOptionData<T>, event: Event
在发生 select 事件时触发。
插槽
插槽名参数描述
item
{ item: MenuOptionData<T>; isTrigger?: boolean; }
项插槽的自定义内容。
item-leading
{ item: MenuOptionData<T>; }
用于项目引导槽位的自定义内容。
item-trailing
{ item: MenuOptionData<T>; }
用于项目尾部槽位的自定义内容。
item-trigger-icon
{ item: MenuOptionData<T>; }
项目触发图标槽位的自定义内容。
item-link-icon
{ item: MenuOptionData<T>; }
项目链接图标槽位的自定义内容。
trigger
((data: { item: MenuOptionData<T>; }) => any)
触发器插槽的自定义内容。 可选:当消费者未提供内容时,`MenubarCompact` 会渲染完整的默认触发器内容(图标、 标签、链接图标、尾部插槽)。
more-trigger
—
当 `collapsible` 时,为末尾的“更多”触发器提供自定义内容。

MenubarContent

25 属性7 事件
属性
属性名类型默认值描述
popupProps
MenuPopupProps
—
转发给弹出窗口元素的属性。
placement
Placement
undefined
浮动元素的位置。 若使用该属性,它将覆盖 `side` 和 `align` 属性。
side
Side
'bottom'
打开时优先渲染的触发器一侧。当发生碰撞且 enableAvoidCollisions 启用时,该方向将被反转。
sideOffset
number
0
距触发器的像素距离。
sideFlip
boolean
true
遇到边界时,请翻转至另一侧。
align
Align
'center'
首选与触发条件保持一致。若发生冲突,则可能调整。
alignOffset
number
0
相对于 `start` 或 `end` 对齐选项的像素偏移量。
alignFlip
boolean
true
当与边界发生冲突时,翻转对齐方式。 此情况仅在 `prioritizePosition` 为 true 时才会发生。
avoidCollisions
boolean
true
当值为 `true` 时,将覆盖“侧边”和“对齐”首选项,以避免与边界边缘发生冲突。
collisionBoundary
Element | (Element | null)[] | null
[ ]
用作碰撞边界的元素。默认情况下,该边界为视口,但您可以提供额外的 元素以纳入此检查范围。
collisionPadding
Padding
0
从边界边缘开始,碰撞检测应发生的距离(以像素为单位)。接受一个数字( 所有边均相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。
arrowPadding
number
0
箭头与内容边缘之间的间距。如果您的内容使用了 border-radius,这将防止内容 溢出到角落。
hideShiftedArrow
boolean
true
当值为 `true` 时,若无法将箭头居中对齐 到引用元素上,则隐藏该箭头。
sticky
'partial' | 'always'
'partial'
在对齐轴上的“粘附”行为。`partial` 会在触发器至少部分位于边界内时将内容保留在边界内,而 “always” 则无论触发器是否位于边界内,都会将内容保留在边界内。
hideWhenDetached
boolean
false
当触发器被完全遮挡时,是否隐藏内容。
positionStrategy
'fixed' | 'absolute'
'fixed'
要使用的 CSS `position` 属性的类型。
updatePositionStrategy
'always' | 'optimized'
'optimized'
在每个动画帧中更新浮动元素位置的策略。
disableUpdateOnLayoutShift
boolean
false
当布局发生变化时,是否禁用内容的更新位置。
prioritizePosition
boolean
false
强制内容位于视口内。可能会与参考元素重叠,这可能并非预期效果。
reference
ReferenceElement
—
将作为浮动元素定位参考点的自定义元素或虚拟元素。如果 提供了该元素,它将替换默认的锚点元素。
trapFocus
boolean
modal
弹出窗口打开时,焦点是否被困在其中(Tab 键在层内循环,且 模态层的页面滚动被锁定)。
disableHoverableContent
boolean
false
当设置为 `true` 时,鼠标悬停会关闭弹出窗口而非保持其打开状态(宽限区域已禁用, 因此离开触发区域会立即关闭该层)。
onGracePointerExit
(() => void)
—
当指针最终离开宽限区域时触发的回调。允许上层组件(例如 Tooltip)在无需注册自己的第二个宽限区域的情况下,执行区域范围内的关闭逻辑。
forceMount
boolean
—
用于在需要更多控制时强制挂载。 在使用 Vue 动画库控制动画时非常有用。
loop
boolean
false
键盘导航是否应循环往复
事件
事件名参数描述
escapeKeyDown
KeyboardEvent
当 Esc 键被按下时触发的事件处理程序。可被阻止。
pointerDownOutside
PointerDownOutsideEvent
当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。
focusOutside
FocusOutsideEvent
当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown` 事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。
openAutoFocus
Event
在打开页面时自动聚焦时触发的事件处理程序。可被阻止。
closeAutoFocus
Event
在关闭时自动聚焦时触发的事件处理程序。可被阻止。
entryFocus
Event
在条目获得焦点时触发。

MenubarGroup

MenubarGroupLabel

MenubarItem

MenubarItemIndicator

MenubarMenu

1 属性
属性
属性名类型默认值描述
value
DefinedValue
—
一个唯一值,用于在受控时将触发器与活动根值关联起来。

MenubarMenus<T>

12 属性
属性
属性名类型默认值描述
items
MenuOptionData<T>[]
—
顶级项目应渲染为可见的触发器。
moreItems
MenuOptionData<T>[]
—
项目已折叠至末尾的“更多”菜单中。
rootProps
{ [x: string]: unknown; }
—
转发给菜单栏根节点的属性。
listeners
{ [x: string]: unknown; }
—
将监听器转发至菜单栏根节点。
optionsProps
{ [x: string]: unknown; }
—
这些 prop 会被转发至每个已展开菜单的菜单选项中。
linkProps
LinkExtraProps
—
传递给链接触发器的 props。
contentProps
MenubarContentProps
—
已将属性转发至各菜单的内容中。
portalProps
MenuPortalProps
—
转发至各菜单入口页面的 props。
getTriggerProps
(item: MenuOptionData<T>) => MenubarTriggerProps
—
解析顶级触发项的有效 props。
moreTriggerProps
{ [x: string]: unknown; }
—
将 props 转发给末尾的“more”触发器。
moreLabel
string
—
尾部“more”触发器的标签。
moreIcon
IconValue
—
尾部“更多”触发器的图标。

MenubarPortal

MenubarRadioGroup

MenubarRadioItem

MenubarRoot<T>

9 属性1 事件
属性
属性名类型默认值描述
modelValue
T
—
要打开的菜单的受控值。可作为 `v-model` 使用。
defaultValue
T
—
初始渲染时应打开的菜单值。
dir
Direction
—
如适用,请保留菜单栏的阅读方向。
loop
boolean
—
当值为 `true` 时,键盘导航会在最后一次触发点与第一个触发点之间循环。
trigger
MenubarTriggerType
'click'
菜单栏的触发类型。 - `click`:点击触发器时将打开菜单(将鼠标悬停在 已打开的菜单栏上仍可在菜单之间切换)。 - `hover`:将鼠标悬停在触发器上时将打开菜单。
delayDuration
number
150
从指针进入触发器到菜单在悬停模式下 打开所花费的时间。
skipDelayDuration
number
300
用户在触发延迟之前,还有多少时间可以输入另一个触发条件。 延迟。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
事件
事件名参数描述
update:modelValue
T
当模型值发生变化时触发。

MenubarSeparator

MenubarSub

MenubarSubContent

23 属性7 事件
属性
属性名类型默认值描述
loop
boolean
false
键盘导航是否应循环往复
placement
Placement
undefined
浮动元素的位置。 若使用该属性,它将覆盖 `side` 和 `align` 属性。
popupProps
MenuPopupProps
—
转发给弹出窗口元素的属性。
sideOffset
number
0
距触发器的像素距离。
arrowPadding
number
0
箭头与内容边缘之间的间距。如果您的内容使用了 border-radius,这将防止内容 溢出到角落。
updatePositionStrategy
'always' | 'optimized'
'optimized'
在每个动画帧中更新浮动元素位置的策略。
sideFlip
boolean
true
遇到边界时,请翻转至另一侧。
alignOffset
number
0
相对于 `start` 或 `end` 对齐选项的像素偏移量。
alignFlip
boolean
true
当与边界发生冲突时,翻转对齐方式。 此情况仅在 `prioritizePosition` 为 true 时才会发生。
avoidCollisions
boolean
true
当值为 `true` 时,将覆盖“侧边”和“对齐”首选项,以避免与边界边缘发生冲突。
collisionBoundary
Element | (Element | null)[] | null
[ ]
用作碰撞边界的元素。默认情况下,该边界为视口,但您可以提供额外的 元素以纳入此检查范围。
collisionPadding
Padding
0
从边界边缘开始,碰撞检测应发生的距离(以像素为单位)。接受一个数字( 所有边均相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。
hideShiftedArrow
boolean
true
当值为 `true` 时,若无法将箭头居中对齐 到引用元素上,则隐藏该箭头。
sticky
'partial' | 'always'
'partial'
在对齐轴上的“粘附”行为。`partial` 会在触发器至少部分位于边界内时将内容保留在边界内,而 “always” 则无论触发器是否位于边界内,都会将内容保留在边界内。
hideWhenDetached
boolean
false
当触发器被完全遮挡时,是否隐藏内容。
positionStrategy
'fixed' | 'absolute'
'fixed'
要使用的 CSS `position` 属性的类型。
disableUpdateOnLayoutShift
boolean
false
当布局发生变化时,是否禁用内容的更新位置。
prioritizePosition
boolean
false
强制内容位于视口内。可能会与参考元素重叠,这可能并非预期效果。
reference
ReferenceElement
—
将作为浮动元素定位参考点的自定义元素或虚拟元素。如果 提供了该元素,它将替换默认的锚点元素。
trapFocus
boolean
modal
弹出窗口打开时,焦点是否被困在其中(Tab 键在层内循环,且 模态层的页面滚动被锁定)。
disableHoverableContent
boolean
false
当设置为 `true` 时,鼠标悬停会关闭弹出窗口而非保持其打开状态(宽限区域已禁用, 因此离开触发区域会立即关闭该层)。
onGracePointerExit
(() => void)
—
当指针最终离开宽限区域时触发的回调。允许上层组件(例如 Tooltip)在无需注册自己的第二个宽限区域的情况下,执行区域范围内的关闭逻辑。
forceMount
boolean
—
用于在需要更多控制时强制挂载。 在使用 Vue 动画库控制动画时非常有用。
事件
事件名参数描述
escapeKeyDown
KeyboardEvent
当 Esc 键被按下时触发的事件处理程序。可被阻止。
pointerDownOutside
PointerDownOutsideEvent
当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。
focusOutside
FocusOutsideEvent
当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown` 事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。
openAutoFocus
Event
在打开页面时自动聚焦时触发的事件处理程序。可被阻止。
closeAutoFocus
Event
在关闭时自动聚焦时触发的事件处理程序。可被阻止。
entryFocus
Event
在条目获得焦点时触发。

MenubarSubTrigger

4 属性
属性
属性名类型默认值描述
disabled
boolean
—
当值为 `true` 时,禁止用户与该项进行交互。
textValue
string
—
用于联想输入的可选文本。默认情况下,联想输入功能将使用该 项的 `.textContent`。<br> 当内容较为复杂,或其中包含非文本内容时,请使用此选项。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

MenubarTrigger

4 属性
属性
属性名类型默认值描述
type
ButtonType
'button'
按钮元素的类型。可以是 'button'、'submit' 或 'reset' 之一。
disabled
boolean
—
该组件是否已禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

备注

架构与行业对标

能力VeanUIAnt Design MenuElement Plus MenuRadix Menubar
Aria/styled 分离✅ @vean/aria/menubar + scv()❌ 单包❌ 单包✅ @radix-ui/react-menubar
数据驱动 compact API✅ MenubarCompact + 嵌套 items✅ items✅ items❌ 面向 JSX 组合
顶层触发✅ 点击 / 悬停切换 + 方向键✅ 点击 / 悬停✅ 点击 / 悬停✅ 点击 / 悬停 + 方向键
横向键盘漫游✅ Roving Focus + loop✅✅✅
菜单间切换✅ ArrowRight / ArrowLeft 跨菜单切换✅✅✅
嵌套子菜单✅ 任意层级(复用 menu 层)✅ SubMenu✅ el-sub-menu✅
链接型顶层项✅ href / to + target / external / disabled✅ danger 等—✅ LinkItem
禁用✅ 逐项 + 紧凑级整体禁用✅ disabled✅ disabled✅ disabled
受控模式✅ modelValue / defaultValue✅ openKeys / selectedKeys✅ default-active✅ value / onValueChange
方向✅ LTR / RTL + 逻辑方向键✅ RTL✅ RTL✅ RTL
尺寸变体✅ size xs…2xl✅ size✅ size—
菜单项类型✅ 复选框 / 单选 / 分隔符 / 快捷键(复用 menu 层)✅ 全类型✅ 全类型✅ 全类型

运行时注意事项

  1. 打开状态与指针 — 默认模式(trigger="click")下,顶层触发器在 pointerdown 时打开菜单;菜单已打开时再次点击同一触发器会通过 dismissable layer 关闭(“再次点击收起”)。悬停其他触发器则切换打开的菜单。trigger="hover" 模式悬停即展开,delayDuration(默认 150ms)控制展开延迟,skipDelayDuration(默认 300ms)控制连开窗口内的无延迟切换。
  2. 链接型顶层项 — 提供 href / to 的项不渲染下拉内容,其点击 / 键盘激活直接导航;在菜单打开时悬停到链接项会收起当前菜单并把焦点移到链接。
  3. 禁用语义 — item.disabled 作用于单个顶层项:渲染 aria-disabled、tabindex="-1" 并阻断点击与键盘激活;紧凑组件级 disabled 会禁用全部触发器(含链接型)。子菜单中的禁用项遵循 menu 层语义。
  4. Portal 与定位 — 下拉内容默认通过 Teleport 传送到 body(可用 portalProps.disabled 关闭)。若内容出现在错误位置,请检查是否处于 transform / 动画容器祖先内;定位依赖 getBoundingClientRect 测量。
  5. 受控 / 非受控 — 提供 modelValue 时,内部写入仅触发 update:modelValue,打开的菜单完全跟随 prop;未受控时 defaultValue 指定初始打开项。
  6. 焦点归还 — 键盘路径(Escape / 方向键切换)会精确归还焦点到触发器;指针路径(点击外部关闭)不主动移动焦点,符合"指针交互不劫持焦点"的惯例。
  7. RTL — 设置 dir="rtl" 后方向键语义镜像(ArrowLeft 变为"下一个"),菜单布局依赖逻辑属性自动翻转。
  8. 溢出折叠 — 开启 collapsible 后,菜单栏内容超出容器宽度时末尾项合并进"更多"菜单;测量基于渲染后的真实布局,容器的父级需提供固定/受限宽度(例如 max-w-*)。若菜单栏处于 flex 容器且未收缩,请给父容器设置 min-w-0 或宽度约束。

常见问题

如何让顶层项直接跳转而不展开下拉?

给项设置 href 或 to 即可——链接型顶层项渲染为 <a>,不渲染下拉内容;同时可用 target / external 控制打开方式。

如何精确控制当前打开的菜单?

使用 v-model 绑定 modelValue。顶层项的 value 成为受控值,切换即触发 update:modelValue;外部改值会同步打开对应菜单。未受控时用 defaultValue 指定初始打开的项。

如何禁用整个菜单栏或单个项?

整体禁用传 disabled 给 SMenubar;单个顶层项禁用在该项上设置 disabled: true。禁用项渲染 aria-disabled、移出 Tab 顺序,并阻断点击与键盘激活。

键盘如何操作?

Tab 进入菜单栏后,ArrowLeft / ArrowRight 在触发器间移动;Enter / Space 切换菜单、ArrowDown 打开;菜单内方向键漫游条目,ArrowRight / ArrowLeft 切换相邻顶层菜单,Escape 关闭。禁用项不在 Tab 顺序中。

能在子菜单里用复选框或单选吗?

可以——下拉内容复用 menu 层的能力:item-checked 槽位、MenuCheckboxItem / MenuRadioItem 以及 separator / shortcut 均可用;紧凑用法中给子项传对应字段即可。

为什么悬停链接型项时菜单会收起?

链接型顶层项没有下拉内容,指针进入时菜单栏会收起当前打开的菜单并把焦点移到该链接——这与 Radix Menubar 的链接项行为一致,避免焦点停留在已关闭菜单的触发器上。

如何让菜单在悬停时自动展开(而不是点击)?

给 SMenubar 传 trigger="hover" 即可。悬停触发器会展开菜单(delayDuration 控制展开延迟,skipDelayDuration 控制连开窗口);指针可在菜单栏与菜单内容之间移动而不误关。键盘操作(方向键 / Enter / Space / Escape)在两种模式下完全一致。

菜单项太多放不下怎么办?

给 SMenubar 传 collapsible。当菜单栏内容超出容器宽度时,末尾的顶层项会自动合并进一个"更多"菜单(默认标签 More,可用 moreLabel / moreIcon / moreProps 定制),保证内容宽度不超过容器。容器宽度变化时折叠状态自动重算。

更新日志

版本记录按发布版本分组,便于快速查看这个组件在不同版本里的实际变更。

v0.50.0

2026-10-02

对比版本

修复

当折叠功能被禁用时,移除过时的“更多”菜单

范围: menubar作者: soybeanjs查看提交aeac4

样式

修正触发器中展开状态样式的语法

范围: menubar作者: soybeanjs查看提交74349

修复

当折叠功能被禁用时,移除过时的“更多”菜单

范围: menubar作者: soybeanjs查看提交aeac4

样式

修正触发器中展开状态样式的语法

范围: menubar作者: soybeanjs查看提交74349

v0.30.0

2026-08-20

对比版本

新功能

支持悬停触发,并在内容溢出时显示省略号

范围: menubar作者: soybeanjs查看提交5924e

修复

防止触发点击导致已打开的菜单被关闭

范围: menubar作者: soybeanjs查看提交574b5

文档

将 dialog/select 的端到端基准修复标记为“已验证”

范围: menubar作者: soybeanjs查看提交96d00

文档

更新菜单栏文档、API 和技能

范围: menubar作者: soybeanjs查看提交de78c

新功能

支持悬停触发,并在内容溢出时显示省略号

范围: menubar作者: soybeanjs查看提交5924e

修复

防止触发点击导致已打开的菜单被关闭

范围: menubar作者: soybeanjs查看提交574b5

文档

将 dialog/select 的端到端基准修复标记为“已验证”

范围: menubar作者: soybeanjs查看提交96d00

文档

更新菜单栏文档、API 和技能

范围: menubar作者: soybeanjs查看提交de78c

v0.21.0

2026-05-12

对比版本

修复

加强链接触发器的焦点管理并更新菜单交互逻辑

范围: menubar作者: soybeanfe查看提交2cddd

v0.20.0

2026-05-12

对比版本

优化

删除计算类,简化类绑定

范围: menubar作者: soybeanfe查看提交da103