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

TreeNav

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

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

快速跳转

同分类组件

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

树形导航

概述

TreeNav 是一个数据驱动的水平导航栏,携带持久选择态:顶层条目横向排列,分支项默认悬停展开弹层,选中任意叶子后整条祖先链持续高亮。

STreeNav 是 STreeMenu 的横向版本:两者消费同一份树形 items 数据(TreeNavOptionData)并基于选中值派生高亮,区别在于 TreeNav 的分支渲染为 DropdownMenu 弹层而非折叠分组。逻辑与无障碍语义由 Aria TreeNavCompact 承载,样式通过 scv() 配方注入。

与 Menubar(瞬态"哪个菜单正打开"的命令菜单模型)不同,TreeNav 建模的是选择:打开弹层永远不会激活任何条目——只有叶子被选中才会。选中叶子的祖先链会持续携带高亮标记。

功能特性

  • 持久选择态 — 绑定 modelValue(v-model)或用 defaultValue 设置初始值;弹层关闭后选择依然保留。
  • 高亮派生 — 选中的叶子渲染 data-selected="true",其祖先链上的每一层渲染 data-child-selected;派生复用共享树路径工具,任意深度均可正确传播。
  • 悬停优先的弹层 — 分支弹层默认悬停展开(可用 trigger="click" 覆盖),通过 delayDuration / skipDelayDuration 微调时序。
  • 对齐 TreeMenu 的数据形态 — 一份 items 数组(TreeNavOptionData:value / label / icon / children / href / to / disabled …)与 TreeMenu 的选项模型保持一致;徽标、标签、操作按钮等条目自定义能力通过插槽实现,不再依赖额外数据字段。
  • 链接型顶层项 — 提供 href / to 的顶层项渲染为链接,点击同时更新选择。
  • 溢出折叠 — 开启 collapsible 后,超宽的末尾顶层项自动合并进尾部"更多"弹层,始终贴合容器宽度;可通过 moreLabel / moreIcon / moreProps / more-trigger 插槽定制。
  • 导航语义 — 根元素渲染 <nav>(可用 as 覆写);触发器的 aria-haspopup / aria-expanded、Escape 关闭等语义继承自 DropdownMenu 层。
  • 键盘导航 — 顶层是单一 roving Tab 停留点:←/→ 对所有条目一视同仁地漫游(跳过禁用项、首尾不循环),Home/End 跳转首尾条目;分支弹层的打开走显式按键——Enter/Space(原生按钮语义)或 ↓——弹层一旦打开,按键全部归属 Menu 机制。
  • 逐项与整体禁用 — item.disabled 使单个条目惰性;栏级 disabled 一次禁用全部。
  • 隐藏项 — item.hidden 将条目及其子树从导航栏与弹层中移除;子项全部隐藏的分支按普通叶子渲染。
  • 六种尺寸与两种变体 — size(xs…2xl)加 variant="default"(浅色卡片底)或 variant="nav"(纯净无框)。
  • 插槽透传 — item / item-leading / item-trailing / item-trigger-icon / item-link-icon 同时透传到顶层与弹层内部。
  • Aria 组合 — 无样式数据驱动用法可导入 @vean/aria/tree-nav;弹层选项复用 MenuOptionsCompact。

用法

演示

基础

GitHubDiscord

选择态

Selected: email — opening a popup never marks a branch active; only selection does.

链接项

禁用

溢出折叠

Discord

API

Aria 层

6

TreeNav

31 属性2 事件6 插槽
属性
属性名类型默认值描述
class
ClassValue
—
树导航的根类。
size
ThemeSize
—
组件的视觉尺寸。
ui
Partial<TreeNavUi>
—
该组件的按槽类重写。
collapsible
boolean
false
是否将顶层的溢出项目折叠到末尾的“更多”分支 弹出窗口中,以确保进度条始终能完全容纳在其容器内。
modelValue
string
—
当前所选项的值。可作为 `v-model` 使用。
defaultValue
string
—
初始渲染时应选中的项的值。
dir
Direction
—
如适用,请标注组件的阅读方向。
trigger
DropdownMenuTriggerType
'hover'
分支弹出窗口的打开方式。 - `click`:点击触发器时,弹出窗口将打开。 - `hover`:将鼠标悬停在触发器上时,弹出窗口将打开。
delayDuration
number
150
从指针进入分支触发器开始,直到 悬停模式下弹出窗口打开为止的时间间隔。
skipDelayDuration
number
300
用户有多少时间可以触发另一个分支,而不会 再次产生延迟。
placement
Placement
'bottom-start'
分支弹出窗口相对于其触发点的首选位置。
showArrow
boolean
false
分支弹出窗口是否显示箭头。
disabled
boolean
—
整个导航栏是否被禁用。
linkProps
LinkExtraProps
—
传递给链接项的 link 元素的属性。
itemProps
MenuItemProps
—
转发至弹出项的 item 元素的属性。
groupLabelProps
MenuGroupLabelProps
—
转发至弹出窗口组标签的 group label 元素的属性。
shortcutProps
MenuShortcutProps
—
转发至弹出项快捷方式元素的属性。
separatorProps
MenuSeparatorProps
—
传递给弹出式分隔符的分隔符元素的属性。
subTriggerProps
MenuSubTriggerProps
—
转发给弹出窗口分支子触发器元素的属性。
subContentProps
MenuSubContentProps
—
属性将转发至弹出窗口分支的子内容元素。
portalProps
MenuPortalProps
—
转发至弹出窗口(popups)的 portal 元素的属性。
popupProps
MenuPopupProps
—
转发给弹出窗口(popups)的弹出元素的属性。
triggerProps
DropdownMenuTriggerProps
—
转发给分支弹出窗口触发元素的属性。
arrowProps
MenuArrowProps
—
转发给弹出窗口箭头元素的属性。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
items
TreeNavOptionData<TreeNavBaseOptionData>[]
—
顶级项目应渲染为可见条目。
moreItems
TreeNavOptionData<TreeNavBaseOptionData>[]
—
项目已折叠至末尾的“更多”弹出窗口中。
moreLabel
string
'More'
尾部“more”触发器的标签。
moreIcon
IconValue
'lucide:ellipsis'
尾部“更多”触发器的图标。
moreProps
ButtonProps
—
传递给末尾“更多”触发按钮的属性。
事件
事件名参数描述
update:modelValue
string
当选定值发生变化时触发。
select
TreeNavOptionData<TreeNavBaseOptionData>, event: Event
当选中某项时触发。
插槽
插槽名参数描述
item
{ item: MenuOptionData<DefinedValue>; isTrigger?: boolean; }
项插槽的自定义内容。
item-leading
{ item: MenuOptionData<DefinedValue>; }
用于项目引导槽位的自定义内容。
item-trailing
{ item: MenuOptionData<DefinedValue>; }
用于项目尾部槽位的自定义内容。
item-trigger-icon
{ item: MenuOptionData<DefinedValue>; }
项目触发图标槽位的自定义内容。
item-link-icon
{ item: MenuOptionData<DefinedValue>; }
项目链接图标槽位的自定义内容。
more-trigger
TreeNavMoreEntry
若存在尾随的“更多”触发器,请提供相应自定义内容。

TreeNavCompact

28 属性2 事件6 插槽
属性
属性名类型默认值描述
collapsible
boolean
false
是否将顶层的溢出项目折叠到末尾的“更多”分支 弹出窗口中,以确保进度条始终能完全容纳在其容器内。
modelValue
string
—
当前所选项的值。可作为 `v-model` 使用。
defaultValue
string
—
初始渲染时应选中的项的值。
dir
Direction
—
如适用,请标注组件的阅读方向。
trigger
DropdownMenuTriggerType
'hover'
分支弹出窗口的打开方式。 - `click`:点击触发器时,弹出窗口将打开。 - `hover`:将鼠标悬停在触发器上时,弹出窗口将打开。
delayDuration
number
150
从指针进入分支触发器开始,直到 悬停模式下弹出窗口打开为止的时间间隔。
skipDelayDuration
number
300
用户有多少时间可以触发另一个分支,而不会 再次产生延迟。
placement
Placement
'bottom-start'
分支弹出窗口相对于其触发点的首选位置。
showArrow
boolean
false
分支弹出窗口是否显示箭头。
disabled
boolean
—
整个导航栏是否被禁用。
linkProps
LinkExtraProps
—
传递给链接项的 link 元素的属性。
itemProps
MenuItemProps
—
转发至弹出项的 item 元素的属性。
groupLabelProps
MenuGroupLabelProps
—
转发至弹出窗口组标签的 group label 元素的属性。
shortcutProps
MenuShortcutProps
—
转发至弹出项快捷方式元素的属性。
separatorProps
MenuSeparatorProps
—
传递给弹出式分隔符的分隔符元素的属性。
subTriggerProps
MenuSubTriggerProps
—
转发给弹出窗口分支子触发器元素的属性。
subContentProps
MenuSubContentProps
—
属性将转发至弹出窗口分支的子内容元素。
portalProps
MenuPortalProps
—
转发至弹出窗口(popups)的 portal 元素的属性。
popupProps
MenuPopupProps
—
转发给弹出窗口(popups)的弹出元素的属性。
triggerProps
DropdownMenuTriggerProps
—
转发给分支弹出窗口触发元素的属性。
arrowProps
MenuArrowProps
—
转发给弹出窗口箭头元素的属性。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
items
TreeNavOptionData<TreeNavBaseOptionData>[]
—
顶级项目应渲染为可见条目。
moreItems
TreeNavOptionData<TreeNavBaseOptionData>[]
—
项目已折叠至末尾的“更多”弹出窗口中。
moreLabel
string
'More'
尾部“more”触发器的标签。
moreIcon
IconValue
'lucide:ellipsis'
尾部“更多”触发器的图标。
moreProps
ButtonProps
—
传递给末尾“更多”触发按钮的属性。
事件
事件名参数描述
update:modelValue
string
当选定值发生变化时触发。
select
TreeNavOptionData<TreeNavBaseOptionData>, event: Event
当选中某项时触发。
插槽
插槽名参数描述
item
{ item: MenuOptionData<DefinedValue>; isTrigger?: boolean; }
项插槽的自定义内容。
item-leading
{ item: MenuOptionData<DefinedValue>; }
用于项目引导槽位的自定义内容。
item-trailing
{ item: MenuOptionData<DefinedValue>; }
用于项目尾部槽位的自定义内容。
item-trigger-icon
{ item: MenuOptionData<DefinedValue>; }
项目触发图标槽位的自定义内容。
item-link-icon
{ item: MenuOptionData<DefinedValue>; }
项目链接图标槽位的自定义内容。
more-trigger
TreeNavMoreEntry
若存在尾随的“更多”触发器,请提供相应自定义内容。

TreeNavOptionCompact

2 属性
属性
属性名类型默认值描述
item
TreeNavOptionData<T extends TreeNavBaseOptionData = TreeNavBaseOptionData>
—
当前条目数据。
childSelected
boolean
—
所选叶节点是否位于此分支子树中。

TreeNavOptionsCompact

5 属性6 插槽
属性
属性名类型默认值描述
items
TreeNavOptionData<TreeNavBaseOptionData>[]
—
顶级项目应渲染为可见条目。
moreItems
TreeNavOptionData<TreeNavBaseOptionData>[]
—
项目已折叠至末尾的“更多”弹出窗口中。
moreLabel
string
'More'
尾部“more”触发器的标签。
moreIcon
IconValue
'lucide:ellipsis'
尾部“更多”触发器的图标。
moreProps
ButtonProps
—
传递给末尾“更多”触发按钮的属性。
插槽
插槽名参数描述
item
{ item: MenuOptionData<DefinedValue>; isTrigger?: boolean; }
项插槽的自定义内容。
item-leading
{ item: MenuOptionData<DefinedValue>; }
用于项目引导槽位的自定义内容。
item-trailing
{ item: MenuOptionData<DefinedValue>; }
用于项目尾部槽位的自定义内容。
item-trigger-icon
{ item: MenuOptionData<DefinedValue>; }
项目触发图标槽位的自定义内容。
item-link-icon
{ item: MenuOptionData<DefinedValue>; }
项目链接图标槽位的自定义内容。
more-trigger
TreeNavMoreEntry
若存在尾随的“更多”触发器,请提供相应自定义内容。

TreeNavOverflow

TreeNavRoot

22 属性2 事件1 插槽
属性
属性名类型默认值描述
modelValue
string
—
当前所选项的值。可作为 `v-model` 使用。
defaultValue
string
—
初始渲染时应选中的项的值。
dir
Direction
—
如适用,请标注组件的阅读方向。
trigger
DropdownMenuTriggerType
'hover'
分支弹出窗口的打开方式。 - `click`:点击触发器时,弹出窗口将打开。 - `hover`:将鼠标悬停在触发器上时,弹出窗口将打开。
delayDuration
number
150
从指针进入分支触发器开始,直到 悬停模式下弹出窗口打开为止的时间间隔。
skipDelayDuration
number
300
用户有多少时间可以触发另一个分支,而不会 再次产生延迟。
placement
Placement
'bottom-start'
分支弹出窗口相对于其触发点的首选位置。
showArrow
boolean
false
分支弹出窗口是否显示箭头。
disabled
boolean
—
整个导航栏是否被禁用。
linkProps
LinkExtraProps
—
传递给链接项的 link 元素的属性。
itemProps
MenuItemProps
—
转发至弹出项的 item 元素的属性。
groupLabelProps
MenuGroupLabelProps
—
转发至弹出窗口组标签的 group label 元素的属性。
shortcutProps
MenuShortcutProps
—
转发至弹出项快捷方式元素的属性。
separatorProps
MenuSeparatorProps
—
传递给弹出式分隔符的分隔符元素的属性。
subTriggerProps
MenuSubTriggerProps
—
转发给弹出窗口分支子触发器元素的属性。
subContentProps
MenuSubContentProps
—
属性将转发至弹出窗口分支的子内容元素。
portalProps
MenuPortalProps
—
转发至弹出窗口(popups)的 portal 元素的属性。
popupProps
MenuPopupProps
—
转发给弹出窗口(popups)的弹出元素的属性。
triggerProps
DropdownMenuTriggerProps
—
转发给分支弹出窗口触发元素的属性。
arrowProps
MenuArrowProps
—
转发给弹出窗口箭头元素的属性。
asChild
boolean
—
将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。
as
AsTag | Component
'div'
该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。
事件
事件名参数描述
update:modelValue
string
当选定值发生变化时触发。
select
TreeNavOptionData<TreeNavBaseOptionData>, event: Event
当选中某项时触发。
插槽
插槽名参数描述
default
—
导航根节点内渲染的默认内容。

备注

各导航组件如何选型

组件状态模型方向适用场景
SMenubar打开的菜单(modelValue)横向应用命令菜单(File/Edit)
SNavMenu高亮项(modelValue)横向站点级导航 + 浮层面板
STreeMenu持久选择态纵向侧边栏导航
STreeNav持久选择态横向顶部导航栏

运行时注意事项

  1. 打开 ≠ 激活 — 弹层打开状态是 DropdownMenu 内部管理的瞬时 UI 态;只有叶子选中才更新 data-selected。不要沿用 SMenubar 的 modelValue 语义。
  2. 折叠后的高亮一致性 — 选中项被收进"更多"弹层后,其可见祖先仍显示 data-child-selected,因为派生始终基于完整的 items 列表。
  3. 折叠测量 — 与 Menubar 的溢出折叠一样,测量在挂载后基于真实布局进行;父容器请提供受限宽度(如 max-w-* / 固定宽度)。首帧可能先全量渲染再收缩。
  4. 受控模式 — 提供 modelValue 时内部只触发 update:modelValue;非受控用法用 defaultValue 设定初始值。
  5. 键盘模型 — 弹层关闭时 ←/→(及 Home/End)通过 roving tabindex 在顶层漫游;分支触发器与其他条目一视同仁,方向键只移动、不打开弹层。打开弹层走 Enter/Space 或 ↓(焦点随后落入首个菜单项);弹层一旦打开,所有按键归属 Menu(弹层内 ↑/↓,Escape 关闭并归还焦点到触发器),hover 弹层在焦点离开触发器时自动收起。

FAQ

导航栏支持哪些键盘快捷键?

←/→ 在顶层条目间漫游(Home/End 跳转首尾)——分支触发器同样只是漫游目标,方向键只移动、不会打开弹层。弹层通过分支触发器上的 Enter/Space 或 ↓ 打开(焦点落入首个菜单项)。方向键从不改变选中项——选中只在显式激活(点击,或叶子上的 Enter/Space)时发生。

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

给该条目设置 href 或 to——链接型条目渲染为 <a> 元素,点击同时更新选择。

如何精确控制哪个条目保持高亮?

绑定 v-model 即可。选中的值会与整棵 items 树比对:命中的叶子获得 data-selected,其祖先获得 data-child-selected。

为什么悬停分支不会让它变为激活?

打开弹层是瞬时状态而非选择——请在弹层内选中某个叶子。这与 STreeMenu 中"容器节点不携带 active 态"的行为一致。

导航栏放不下怎么办?

传入 collapsible。超出容器宽度的末尾条目会自动合并进"更多"弹层(默认文本 More),并在容器尺寸变化时自动重算。

更新日志

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

v0.50.0

2026-10-02

对比版本

样式

当折叠功能被禁用时,移除过时的“more”分支

范围: tree-nav作者: soybeanjs查看提交98589

样式

当折叠功能被禁用时,移除过时的“more”分支

范围: tree-nav作者: soybeanjs查看提交98589

v0.40.0

2026-09-14

对比版本

修复

采用菜单栏风格的箭头切换,用于打开分支弹出窗口

范围: tree-nav作者: soybeanfe查看提交f136e

重构

提取 TreeNavOverflow 并优化选中状态的样式

范围: tree-nav作者: soybeanfe查看提交a0ea9

修复

采用菜单栏风格的箭头切换,用于打开分支弹出窗口

范围: tree-nav作者: soybeanfe查看提交f136e

重构

提取 TreeNavOverflow 并优化选中状态的样式

范围: tree-nav作者: soybeanfe查看提交a0ea9