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

NavMenu

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

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

快速跳转

同分类组件

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

NavMenu

概览

NavMenu 用于构建站点级横向或纵向导航,共享一个浮层表面。它接替了已退役的 NavigationMenu 家族(见 NavMenu 迁移指南),直接建模在 Popper 原语之上:整个 viewport 就是单个 PopperPositioner,其 reference 动态切换到激活触发器,所有悬停时序运行在单个共享 Popper 悬停状态机上,并通过 pendingValue 做值路由。

SNavMenu 是数据驱动组合:传 items 数组即可渲染 nav > ul > li 结构、触发器/内容对、指示器与浮动 viewport。样式通过 scv() recipe 注入。

需要无样式、数据驱动的用法时,导入 @vean/aria/nav-menu。

功能特性

  • 单共享 Popper 模型 — 一个 PopperRoot、一个 PopperPositioner(即 viewport),reference 动态切换到激活触发器。定位(Floating UI)、grace 走廊与 Escape/外部点击关闭全部由 positioner 免费提供。
  • 值路由 — 悬停时序(打开延迟、跳延时窗口)运行在共享状态机上;最近悬停触发器的值路由进 modelValue,切换触发器即时完成。
  • 点击 / 悬停双触发 — 默认悬停打开、点击切换;disableClickTrigger / disableHoverTrigger 可单独关闭某一种触发方式。
  • Grace 走廊 — 触发器与打开的 viewport 之间由真实几何走廊保护(无防抖),skipDelayDuration 与 disablePointerLeaveClose 调节关闭行为。
  • 子菜单浮层 — 带 children 的项在其触发器旁打开浮动 viewport,支持箭头指示器与 unmountOnHide 控制卸载。
  • 隐藏项 — hidden 将条目及其整棵子树从根列表与嵌套浮层中移除;子项全部隐藏的条目按叶子链接渲染。
  • 键盘导航 — 方向键在项间移动焦点;Enter / Space 激活链接或切换子菜单;入口方向键将焦点送入内容;Escape 关闭并归还焦点到触发器。
  • 弹层箭头 — viewport 携带 PopperArrow 指向激活触发器;其摆放与旋转由 Floating UI 的 arrow middleware 决定,切换触发器时随 viewport 一起滑动。
  • 受控 / 非受控 — 提供 modelValue 时高亮跟随 prop 并触发 update:modelValue;否则用 defaultValue 做非受控初始值。
  • 双向支持 — orientation 支持横向 / 纵向;dir 支持 LTR / RTL 逻辑定位。
  • 六档尺寸 — size(xs…2xl)覆盖列表、触发器、viewport 与链接的间距和字号。
  • Aria 组合 — NavMenuRoot / List / Item / Trigger / Content / Link / Viewport 及 Compact 系列由 @vean/aria/nav-menu 导出。

用法

示例

Basic

Nested

API

Aria 层

12

NavMenu

21 属性2 事件6 插槽
属性
属性名类型默认值描述
class
ClassValue
—
应用于根元素的额外类名。
size
ThemeSize
—
组件的视觉尺寸。
ui
Partial<NavMenuUi>
—
该组件的按槽类重写。
items
NavMenuOptionData[]
—
导航菜单中要渲染的项目。
modelValue
string
—
活动项的受控值。可作为 `v-model` 使用。
defaultValue
string
—
初始渲染时应处于活动状态的项的值。
dir
Direction
—
菜单的阅读方向。
orientation
DataOrientation
—
菜单的排列方向。
delayDuration
number
200
从指针进入触发区到子菜单打开所花费的时间。
skipDelayDuration
number
300
用户在触发延迟之前,有多少时间可以输入另一个触发条件。
disableClickTrigger
boolean
false
如果设置为 `true`,则无法通过点击触发器打开菜单。
disableHoverTrigger
boolean
false
如果设置为 `true`,则无法通过将鼠标悬停在触发器上打开菜单。
disablePointerLeaveClose
boolean
false
如果设置为 `true`,当指针移出内容区域时,菜单不会关闭。
itemProps
NavMenuItemProps
—
转发给 item 元素的属性。
linkProps
Omit<NavMenuLinkProps, LinkBasePropsKey>
—
传递给 link 元素的属性。
subTriggerProps
NavMenuSubTriggerProps
—
转发给嵌套弹出触发元素的属性。
subContentProps
NavMenuSubContentProps
—
转发给嵌套的 flyout 内容元素的属性。
triggerProps
NavMenuTriggerProps
—
转发给触发元素的属性。
contentProps
NavMenuContentProps
—
转发给内容元素的属性。
listProps
NavMenuListProps
—
转发给列表元素的属性。
viewportProps
NavMenuViewportProps
—
转发给视口元素的属性。
事件
事件名参数描述
update:modelValue
string
当模型值发生变化时触发。
select
CustomEvent<{ originalEvent: Event; }>
当选中链接时触发。
插槽
插槽名参数描述
item
props: { item: NavMenuOptionData; isTrigger?: boolean; }
—
item-leading
props: { item: NavMenuOptionData; }
—
item-trailing
props: { item: NavMenuOptionData; }
—
item-link-icon
props: { item: NavMenuOptionData; }
—
item-trigger-icon
props: { item: NavMenuOptionData; }
—
item-children
props: { item: NavMenuOptionData; }
—

NavMenuCompact

18 属性2 事件6 插槽
属性
属性名类型默认值描述
items
NavMenuOptionData[]
—
导航菜单中要渲染的项目。
modelValue
string
—
活动项的受控值。可作为 `v-model` 使用。
defaultValue
string
—
初始渲染时应处于活动状态的项的值。
dir
Direction
—
菜单的阅读方向。
orientation
DataOrientation
—
菜单的排列方向。
delayDuration
number
200
从指针进入触发区到子菜单打开所花费的时间。
skipDelayDuration
number
300
用户在触发延迟之前,有多少时间可以输入另一个触发条件。
disableClickTrigger
boolean
false
如果设置为 `true`,则无法通过点击触发器打开菜单。
disableHoverTrigger
boolean
false
如果设置为 `true`,则无法通过将鼠标悬停在触发器上打开菜单。
disablePointerLeaveClose
boolean
false
如果设置为 `true`,当指针移出内容区域时,菜单不会关闭。
itemProps
NavMenuItemProps
—
转发给 item 元素的属性。
linkProps
Omit<NavMenuLinkProps, LinkBasePropsKey>
—
传递给 link 元素的属性。
subTriggerProps
NavMenuSubTriggerProps
—
转发给嵌套弹出触发元素的属性。
subContentProps
NavMenuSubContentProps
—
转发给嵌套的 flyout 内容元素的属性。
triggerProps
NavMenuTriggerProps
—
转发给触发元素的属性。
contentProps
NavMenuContentProps
—
转发给内容元素的属性。
listProps
NavMenuListProps
—
转发给列表元素的属性。
viewportProps
NavMenuViewportProps
—
转发给视口元素的属性。
事件
事件名参数描述
update:modelValue
string
当模型值发生变化时触发。
select
CustomEvent<{ originalEvent: Event; }>
当选中链接时触发。
插槽
插槽名参数描述
item
props: { item: NavMenuOptionData; isTrigger?: boolean; }
—
item-leading
props: { item: NavMenuOptionData; }
—
item-trailing
props: { item: NavMenuOptionData; }
—
item-link-icon
props: { item: NavMenuOptionData; }
—
item-trigger-icon
props: { item: NavMenuOptionData; }
—
item-children
props: { item: NavMenuOptionData; }
—

NavMenuContent

1 属性
属性
属性名类型默认值描述
forceMount
boolean
—
用于在需要更多控制时强制挂载。 在使用 Vue 动画库控制动画时非常有用。

NavMenuItem

1 属性
属性
属性名类型默认值描述
value
string
—
与当前项关联的值。

NavMenuLink

22 属性1 事件
属性
属性名类型默认值描述
selected
boolean
—
将该链接标记为当前选中的页面。
sub
boolean
—
链接是否渲染在子菜单中。当值为 `true` 时,将使用 `subLink` UI 插槽 代替 `link`(与列表的根/子菜单划分相对应)。
replace
boolean
—
调用 `router.replace` 而不是 `router.push`。
disabled
boolean
—
当值为 `true` 时,该链接将被禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
href
string
—
点击链接时应跳转到的 URL。
to
string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric
—
Route Location:点击该链接后应跳转到的位置。
activeClass
string
—
当链接处于活动状态时应用的类
exactActiveClass
string
—
当链接完全有效时应用的类
inactiveClass
string
—
链接处于非活动状态时应应用的类。
prefetchedClass
string
—
一个用于标记已预取链接的类。
external
boolean
—
强制将链接视为外部链接(true)或内部链接(false)。这有助于处理边界情况
ariaCurrentValue
'true' | 'false' | 'page' | 'date' | 'time' | 'step' | 'location'
`'page'`
当链接处于活动状态时,传递给 `aria-current` 属性的值。
viewTransition
boolean
—
如果支持,请将 `router.push()` 返回的 Promise 传递给 `document.startViewTransition()`。
target
(string & {}) | '_blank' | '_parent' | '_self' | '_top' | null
—
将链接的 URL 作为浏览上下文的名称显示在何处。
rel
(string & {}) | 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | null
'noopener noreferrer'
应用于链接的 rel 属性值。对于外部链接,默认值为“noopener noreferrer”。
noRel
boolean
—
如果设置为 true,则不会在链接中添加 rel 属性
prefetch
boolean
—
启用后,将预取视口内链接的中间件、布局和有效载荷。
prefetchOn
'visibility' | 'interaction' | Partial<{ visibility: boolean; interaction: boolean; }>
—
允许控制何时预取链接。默认情况下,仅在可见性发生变化时才会触发预取。
noPrefetch
boolean
—
用于禁用 `prefetch` 属性的逃逸机制。
trailingSlash
'append' | 'remove'
—
一个用于在此特定链接的 `href` 中添加或移除尾部斜杠的选项。 如果提供了此选项,将覆盖全局 `trailingSlash` 选项。
事件
事件名参数描述
select
CustomEvent<{ originalEvent: Event; }>
当选中链接时触发。

NavMenuList

NavMenuOptionCompact

9 属性1 事件6 插槽
属性
属性名类型默认值描述
item
NavMenuOptionData
—
当前条目数据。
itemProps
NavMenuItemProps
—
转发给 item 元素的属性。
linkProps
Omit<NavMenuLinkProps, LinkBasePropsKey>
—
传递给 link 元素的属性。
triggerProps
NavMenuTriggerProps
—
转发给触发元素的属性。
contentProps
NavMenuContentProps
—
转发给内容元素的属性。
viewportProps
NavMenuViewportProps
—
转发给视口元素的属性。
listProps
NavMenuListProps
—
转发给列表元素的属性。
subTriggerProps
NavMenuSubTriggerProps
—
转发给嵌套弹出触发元素的属性。
subContentProps
NavMenuSubContentProps
—
转发给嵌套的 flyout 内容元素的属性。
事件
事件名参数描述
select
CustomEvent<{ originalEvent: Event; }>
当选中链接时触发。
插槽
插槽名参数描述
item
props: { item: NavMenuOptionData; isTrigger?: boolean; }
—
item-leading
props: { item: NavMenuOptionData; }
—
item-trailing
props: { item: NavMenuOptionData; }
—
item-link-icon
props: { item: NavMenuOptionData; }
—
item-trigger-icon
props: { item: NavMenuOptionData; }
—
item-children
props: { item: NavMenuOptionData; }
—

NavMenuRoot

9 属性1 事件
属性
属性名类型默认值描述
modelValue
string
—
活动项的受控值。可作为 `v-model` 使用。
defaultValue
string
—
初始渲染时应处于活动状态的项的值。
dir
Direction
—
菜单的阅读方向。
orientation
DataOrientation
—
菜单的排列方向。
delayDuration
number
200
从指针进入触发区到子菜单打开所花费的时间。
skipDelayDuration
number
300
用户在触发延迟之前,有多少时间可以输入另一个触发条件。
disableClickTrigger
boolean
false
如果设置为 `true`,则无法通过点击触发器打开菜单。
disableHoverTrigger
boolean
false
如果设置为 `true`,则无法通过将鼠标悬停在触发器上打开菜单。
disablePointerLeaveClose
boolean
false
如果设置为 `true`,当指针移出内容区域时,菜单不会关闭。
事件
事件名参数描述
update:modelValue
string
当模型值发生变化时触发。

NavMenuSubContent

2 属性
属性
属性名类型默认值描述
sideOffset
number
—
子触发器与嵌套弹出菜单之间的像素距离。
forceMount
boolean
—
用于在需要更多控制时强制挂载。 在使用 Vue 动画库控制动画时非常有用。

NavMenuSubTrigger

3 属性
属性
属性名类型默认值描述
disabled
boolean
—
触发器是否已禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

NavMenuTrigger

3 属性
属性
属性名类型默认值描述
disabled
boolean
—
触发器是否已禁用。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。

NavMenuViewport

3 属性
属性
属性名类型默认值描述
align
Align
—
将视口与活动触发器对齐。
sideOffset
number
—
触发器与视口之间的距离(以像素为单位)。
forceMount
boolean
—
用于在需要更多控制时强制挂载。 在使用 Vue 动画库控制动画时非常有用。

注意事项

架构

能力NavMenu(Popper 原生)
浮层模型单 PopperRoot + viewport 即 PopperPositioner
定位Floating UI 锚定激活触发器(动态 reference)
悬停延迟共享 Popper 悬停状态机(delayDuration / skipDelayDuration)
grace 走廊positioner 的 useGraceArea 锚定整个 nav
关闭positioner 的 usePopperDismiss(Escape / 外部点击)
值路由共享 RootContext 上的 pendingValue 槽

运行时注意事项

  1. 悬停时序 — 菜单在悬停 delayDuration 后打开;已打开(或上次关闭后 skipDelayDuration 内)时悬停另一触发器即时切换。disablePointerLeaveClose 让指针离开内容时保持打开。
  2. 点击与悬停互斥 — 悬停打开的子菜单会忽略随后的 click(hasPointerMoveOpenedRef 守卫),避免“移动时误关闭”。需要纯点击体验时设置 disableHoverTrigger: true。
  3. 受控 / 非受控 — 提供 modelValue 时,内部写入仅触发 update:modelValue;高亮完全跟随 prop。
  4. 焦点处理 — 内容通过焦点代理参与 Tab 导航;Escape 将焦点归还激活触发器。

FAQ

NavMenu 与已退役的 NavigationMenu 家族有何不同?

NavMenu 放弃了共享测量尺寸的 viewport 与每项 hover root,改用 Popper 原生的单 Root + positioner 模型:Floating UI 定位 viewport,grace 走廊与关闭来自 positioner。代价是用标准浮动弹层取代了旧的尺寸/移动方向动画。NavigationMenu 与 SNavigationMenu 已于 v0.50.0 移除——见迁移指南。

如何只保留点击触发?

设置 disableHoverTrigger: true —— 悬停不再打开子菜单,点击仍可切换。只要悬停则设置 disableClickTrigger: true。

父项可以既是链接又带子菜单吗?

可以 —— 同时给项 href / to 与 children。触发器会渲染为链接;点击已打开的链接触发器会先关闭菜单。

更新日志

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

v0.40.0

2026-09-14

对比版本

新功能

为导航菜单选项添加已选状态支持

范围: nav-menu作者: soybeanfe查看提交b903d

修复

允许子链接标签换行

范围: nav-menu作者: soybeanfe查看提交ad3a7

新功能

为导航菜单选项添加已选状态支持

范围: nav-menu作者: soybeanfe查看提交b903d