TreeView 树形目录
可递归展开的层级数据可视化组件,内置文件夹 / 文件图标,支持键盘导航与受控单选、复选状态。
预览
已选择:button
复选模式
已勾选:1 项
安装
pnpm dlx brutx-vue@latest add tree-view用法
<script setup>
import { ref } from 'vue'
import { TreeView } from 'brutx-ui-vue'
import type { TreeNode } from 'brutx-ui-vue'
const nodes: TreeNode[] = [
{
id: 'src',
label: 'src',
children: [
{ id: 'button', label: 'Button.vue' },
{ id: 'input', label: 'Input.vue' },
],
},
{ id: 'pkg', label: 'package.json' },
]
const selected = ref(null)
</script>
<template>
<TreeView
v-model="selected"
:nodes="nodes"
:default-expanded="['src']"
/>
</template>复选模式
<script setup>
import { ref } from 'vue'
import { TreeView } from 'brutx-ui-vue'
import type { TreeNode } from 'brutx-ui-vue'
const nodes: TreeNode[] = [
{
id: 'src',
label: 'src',
children: [
{ id: 'button', label: 'Button.vue' },
{ id: 'input', label: 'Input.vue', disabled: true },
],
},
]
const checkedIds = ref<string[]>(['button'])
</script>
<template>
<TreeView
v-model:checked-ids="checkedIds"
:nodes="nodes"
selection-mode="checkbox"
:default-expanded="['src']"
/>
</template>变体
selectionMode 支持两种选择模式:
| 变体 | 说明 |
|---|---|
single | 默认单选模式,点击节点时通过 v-model 同步选中 id |
checkbox | 复选模式,每个节点前渲染 Checkbox,支持级联勾选——父节点勾选则所有子孙节点全部勾选;子孙节点部分勾选时父节点呈半选状态(aria-checked="mixed")。勾选项通过 v-model:checkedIds 双向绑定。disabled 为 true 的节点不可勾选 |
数据类型
interface TreeNode {
id: string // 唯一标识
label: string // 显示文本
icon?: string // 节点图标(预留字段,当前未使用)
children?: TreeNode[] // 子节点(省略则为叶节点)
data?: unknown // 自定义附加数据
disabled?: boolean // 是否禁用(checkbox 模式下不可勾选)
isLeaf?: boolean // 是否为叶节点(懒加载模式下用于判断是否可展开)
loaded?: boolean // 是否已加载(懒加载模式下标记子节点是否已加载完成)
loading?: boolean // 是否正在加载(懒加载模式下标记子节点加载状态)
hidden?: boolean // 是否隐藏(节点过滤模式下标记不匹配的节点)
}说明:节点图标当前由组件内部自动根据类型渲染——文件夹节点使用
Folder/FolderOpen图标,叶节点使用File图标,无需手动指定。
导出类型
除了 TreeNode,组件还导出以下类型供 TypeScript 项目使用:
import type { SelectionMode, CheckState } from 'brutx-ui-vue'
type SelectionMode = 'single' | 'checkbox'
type CheckState = 'checked' | 'unchecked' | 'indeterminate'API 参考
TreeView
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
nodes必填 | TreeNode<unknown>[] | — | 树形节点数据源;每个节点由 id、label 及可选的 children、disabled 等字段描述。 |
详情声明类型TreeNode<unknown>[] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
modelValue可空 | string | null | undefined | null | 当前选中节点的 id,通过 v-model 受控;无选中项时为 null。 |
详情声明类型string | null | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
checkedIds | string[] | undefined | []按实例调用工厂函数 | 复选模式下已勾选节点的 id 列表,通过 v-model:checkedIds 受控。 |
详情声明类型string[] | undefined 默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
selectionMode | SelectionMode | undefined | "single" | 选择模式;single 选择一个节点,checkbox 允许勾选多个节点。 |
详情声明类型SelectionMode | undefined 字面量
关联类型 SelectionMode 类型定义 — SelectionModeexport type SelectionMode = 'single' | 'checkbox' 默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
defaultExpanded | string[] | undefined | []按实例调用工厂函数 | 首次渲染时默认展开的节点 id;后续展开状态由组件内部维护。 |
详情声明类型string[] | undefined 默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
class | string | undefined | undefined | 追加到树形列表根容器的自定义 CSS 类。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
draggable | boolean | undefined | false | 启用节点拖拽排序,并在放置后更新节点数据。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
allowDrag | ((node: TreeNode<unknown>) => boolean) | undefined | undefined | 按节点判断是否允许开始拖拽;未提供时所有节点均可拖动。 |
详情声明类型((node: TreeNode<unknown>) => boolean) | undefined 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
allowDrop | ((dragNode: TreeNode<unknown>, dropNode: TreeNode<unknown>, dropType: "before" | "after" | "inner") => boolean) | undefined | undefined | 按拖动节点、目标节点和 before、after 或 inner 位置判断是否允许放置。 |
详情声明类型((dragNode: TreeNode<unknown>, dropNode: TreeNode<unknown>, dropType: "before" | "after" | "inner") => boolean) | undefined 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
lazy | boolean | undefined | false | 启用按需加载节点;展开尚未加载的节点时调用 load。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
load | ((node: TreeNode<unknown>) => Promise<TreeNode<unknown>[]>) | undefined | undefined | 异步加载指定节点的子节点;返回的节点数组会写回树数据。 |
详情声明类型((node: TreeNode<unknown>) => Promise<TreeNode<unknown>[]>) | undefined 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
retryOnError | boolean | undefined | false | 加载失败时显示重试操作;启用后重试会重新请求该节点。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
filterable | boolean | undefined | false | 启用节点过滤能力;通过暴露的 filter 方法提交查询文本。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
filterMethod | ((query: string, node: TreeNode<unknown>) => boolean) | undefined | undefined | 自定义节点匹配规则;返回 true 的节点保留,未提供时按节点 label 匹配查询文本。 |
详情声明类型((query: string, node: TreeNode<unknown>) => boolean) | undefined 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}默认值详情
来源packages/ui/src/components/tree-view/TreeView.vue | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@update:modelValue | [id: string | null] | 选中节点变化时发出新的节点 id;清空选择时发出 null。 |
详情声明类型[id: string | null] 字面量
来源packages/ui/src/components/tree-view/TreeView.vue | ||
@select | [node: TreeNode<unknown>] | 用户选择节点时发出对应的完整 TreeNode 数据。 |
详情声明类型[node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@expand | [id: string, expanded: boolean] | 节点展开状态切换时发出节点 id 与切换后的布尔状态。 |
详情声明类型[id: string, expanded: boolean] 字面量
来源packages/ui/src/components/tree-view/TreeView.vue | ||
@update:checkedIds | [ids: string[]] | 复选集合变化时发出最新的已勾选节点 id 列表。 |
详情声明类型[ids: string[]] 来源packages/ui/src/components/tree-view/TreeView.vue | ||
@update:expanded | [ids: string[]] | 展开集合变化时发出最新的展开节点 id 列表。 |
详情声明类型[ids: string[]] 来源packages/ui/src/components/tree-view/TreeView.vue | ||
@update:nodes | [nodes: TreeNode<unknown>[]] | 拖拽排序改变树结构后发出更新后的完整节点数据。 |
详情声明类型[nodes: TreeNode<unknown>[]] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@check | [node: TreeNode<unknown>, checked: boolean] | 复选状态切换时发出节点数据及切换后的勾选状态。 |
详情声明类型[node: TreeNode<unknown>, checked: boolean] 字面量
关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@node-drag-start | [event: DragEvent, node: TreeNode<unknown>] | 节点拖拽开始时发出原生 DragEvent 和被拖动节点。 |
详情声明类型[event: DragEvent, node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@node-drag-enter | [event: DragEvent, node: TreeNode<unknown>] | 拖动指针进入节点区域时发出 DragEvent 和该节点。 |
详情声明类型[event: DragEvent, node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@node-drag-leave | [event: DragEvent, node: TreeNode<unknown>] | 拖动指针离开节点区域时发出 DragEvent 和该节点。 |
详情声明类型[event: DragEvent, node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@node-drag-over | [event: DragEvent, node: TreeNode<unknown>] | 拖动指针在节点上移动时发出 DragEvent 和该节点。 |
详情声明类型[event: DragEvent, node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@node-drag-end | [event: DragEvent, node: TreeNode<unknown>] | 节点拖拽结束时发出 DragEvent 和被拖动节点。 |
详情声明类型[event: DragEvent, node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
@node-drop | [event: DragEvent, node: TreeNode<unknown>, dropType: "before" | "after" | "inner"] | 节点成功放置时发出 DragEvent、目标节点以及 before、after 或 inner 放置位置。 |
详情声明类型[event: DragEvent, node: TreeNode<unknown>, dropType: "before" | "after" | "inner"] 字面量
关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeView.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
filter | (query: string) => void | 按查询文本过滤节点;清空查询字符串可恢复全部节点。 |
详情声明类型(query: string) => void 来源packages/ui/src/components/tree-view/TreeView.vue | ||
reloadNode | (nodeKey: string) => void | 重新加载指定节点的子节点;用于刷新懒加载数据。 |
详情声明类型(nodeKey: string) => void 来源packages/ui/src/components/tree-view/TreeView.vue | ||
TreeViewNode
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
node必填 | TreeNode<unknown> | — | 此行对应的树节点数据。 |
详情声明类型TreeNode<unknown> 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
selectedId可空 | string | null | undefined | null | 当前选中节点的 id,用于标记此行是否处于选中状态。 |
详情声明类型string | null | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
expandedIds必填 | Set<string> | — | 当前已展开节点 id 集合,用于显示此节点的展开状态。 |
详情声明类型Set<string> 默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
depth | number | undefined | 0 | 节点的树层级深度,用于计算行缩进。 |
详情声明类型number | undefined 默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
isFirstRoot | boolean | undefined | false | 标记此节点是否为根级首项,用于根节点布局。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
selectionMode | SelectionMode | undefined | "single" | 此行使用的选择模式,决定交互是单选还是复选。 |
详情声明类型SelectionMode | undefined 字面量
关联类型 SelectionMode 类型定义 — SelectionModeexport type SelectionMode = 'single' | 'checkbox' 默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
checkedIds | Set<string> | undefined | 按实例调用工厂函数 | 当前已勾选节点 id 集合,用于显示复选状态。 |
详情声明类型Set<string> | undefined 默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
disabled | boolean | undefined | false | 禁用此节点的选择、勾选和键盘激活交互。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/tree-view/TreeViewNode.vue | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@select | [node: TreeNode<unknown>] | 此节点被激活或选中时发出完整节点数据。 |
详情声明类型[node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@toggle | [id: string] | 请求切换展开状态时发出此节点 id。 |
详情声明类型[id: string] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@check | [node: TreeNode<unknown>] | 请求切换复选状态时发出此节点数据。 |
详情声明类型[node: TreeNode<unknown>] 关联类型 TreeNode 类型定义 — TreeNodeexport interface TreeNode<T = unknown> {
/** 节点唯一标识 */
id: string
/** 节点显示文本 */
label: string
/** 节点图标名称或自定义图标类名 */
icon?: string
/** 子节点列表 */
children?: TreeNode<T>[]
/** 自定义业务数据 */
data?: T
/** 是否禁用交互 */
disabled?: boolean
/** 是否叶子节点(懒加载时若为 true 则不展示展开图标) */
isLeaf?: boolean
/** 懒加载子节点是否已加载 */
loaded?: boolean
/** 懒加载是否处于请求中 */
loading?: boolean
/** 过滤搜索时是否隐藏 */
hidden?: boolean
}来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@focus-prev | [] | 请求将焦点移动到上一个可见树节点。 |
详情声明类型[] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@focus-next | [] | 请求将焦点移动到下一个可见树节点。 |
详情声明类型[] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@focus-parent | [] | 请求将焦点移动到父节点。 |
详情声明类型[] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@focus-first-child | [] | 请求将焦点移动到展开后可见的第一个子节点。 |
详情声明类型[] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@focus-first | [] | 请求将焦点移动到树中的第一个可见节点。 |
详情声明类型[] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
@focus-last | [] | 请求将焦点移动到树中的最后一个可见节点。 |
详情声明类型[] 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
focus | () => void | 将焦点移动到此节点对应的树项元素。 |
详情声明类型() => void 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
nodeId | string | 此行对应的节点 id。 |
详情声明类型string 来源packages/ui/src/components/tree-view/TreeViewNode.vue | ||
可访问性
- 键盘操作:遵循 WAI-ARIA TreeView 角色规范
| 按键 | 说明 |
|---|---|
ArrowUp | 聚焦上一个可见节点 |
ArrowDown | 聚焦下一个可见节点 |
ArrowRight | 若节点未展开则展开;若已展开则聚焦第一个子节点 |
ArrowLeft | 若节点已展开则折叠;若已折叠则聚焦父节点 |
Enter / Space | 选中节点(单选模式)或切换勾选状态(复选模式) |
Home | 聚焦第一个节点 |
End | 聚焦最后一个节点 |
- ARIA 属性:使用
role="tree"和role="treeitem"语义化标记;复选模式下使用aria-checked属性(true/false/mixed) - 焦点管理:使用 roving tabindex 管理焦点
拖拽排序
启用 draggable 后节点可拖拽排序。通过 allowDrag 和 allowDrop 精细控制拖拽行为。启用 v-model:nodes 后,drop 时组件自动重排树数据;否则需手动处理 node-drop 事件。
<script setup>
import { ref } from 'vue'
import { TreeView, moveNode } from 'brutx-ui-vue'
import type { TreeNode } from 'brutx-ui-vue'
const nodes = ref<TreeNode[]>([
{
id: 'src',
label: 'src',
children: [
{ id: 'button', label: 'Button.vue' },
{ id: 'input', label: 'Input.vue' },
],
},
{ id: 'pkg', label: 'package.json' },
])
function handleDrop(event: DragEvent, node: TreeNode, dropType: 'before' | 'after' | 'inner') {
// 如果未使用 v-model:nodes,可手动调用 moveNode 重排
// nodes.value = moveNode(nodes.value, draggedNode, node, dropType)
}
</script>
<template>
<TreeView
v-model:nodes="nodes"
:nodes="nodes"
draggable
:allow-drag="(node) => node.id !== 'pkg'"
@node-drop="handleDrop"
/>
</template>工具函数:
import { moveNode } from 'brutx-ui-vue'
// 纯函数,用于手动重排树数据
const newNodes = moveNode(nodes, draggedNode, targetNode, 'before')懒加载
启用 lazy 并提供 load 函数后,展开未加载节点时自动触发异步加载。组件内部通过 loadingKeys 防止并发请求,加载完成后自动标记 loaded 状态。
<script setup>
import { TreeView } from 'brutx-ui-vue'
import type { TreeNode } from 'brutx-ui-vue'
const nodes: TreeNode[] = [
{ id: 'root', label: '根目录', isLeaf: false },
]
async function loadChildren(node: TreeNode): Promise<TreeNode[]> {
const response = await fetch(`/api/children/${node.id}`)
return response.json()
}
</script>
<template>
<TreeView
:nodes="nodes"
lazy
:load="loadChildren"
retry-on-error
/>
</template>TreeNode 懒加载字段:
| 字段 | 类型 | 说明 |
|---|---|---|
isLeaf | boolean | 是否为叶节点,懒加载模式下用于判断是否可展开 |
loaded | boolean | 是否已加载,标记子节点是否已加载完成 |
loading | boolean | 是否正在加载,标记当前加载状态 |
节点过滤
启用 filterable 后,通过组件实例的 filter 方法触发过滤。过滤会递归计算匹配状态,匹配节点及其祖先节点显示,其余隐藏,匹配节点的父级自动展开。
<script setup>
import { ref } from 'vue'
import { TreeView } from 'brutx-ui-vue'
import type { TreeNode } from 'brutx-ui-vue'
const treeRef = ref()
const query = ref('')
const nodes: TreeNode[] = [
{
id: 'src',
label: 'src',
children: [
{ id: 'button', label: 'Button.vue' },
{ id: 'input', label: 'Input.vue' },
],
},
{ id: 'pkg', label: 'package.json' },
]
function handleSearch() {
treeRef.value?.filter(query.value)
}
</script>
<template>
<div>
<input v-model="query" @input="handleSearch" placeholder="搜索节点..." />
<TreeView
ref="treeRef"
:nodes="nodes"
filterable
:default-expanded="['src']"
/>
</div>
</template>重载节点
通过组件实例的 reloadNode 方法可以重置指定节点的 loaded 状态并重新触发懒加载,适用于需要刷新子节点数据的场景。
<script setup>
import { ref } from 'vue'
import { TreeView } from 'brutx-ui-vue'
import type { TreeNode } from 'brutx-ui-vue'
const treeRef = ref()
function refreshNode(nodeKey: string) {
treeRef.value?.reloadNode(nodeKey)
}
</script>
<template>
<TreeView
ref="treeRef"
:nodes="nodes"
lazy
:load="loadChildren"
/>
<button @click="refreshNode('src')">刷新 src 节点</button>
</template>常见问题
Q: 复选模式下,为什么父节点变成了半选状态?
A: 这是级联勾选的设计行为。当父节点的子节点中只有部分被勾选时,父节点会显示为半选状态(aria-checked="mixed"),表示"部分选中"。只有当所有子节点都被勾选时,父节点才会显示为完全勾选状态。反之,勾选父节点会自动勾选其所有子孙节点。
Q: 如何在初始加载时展开特定节点?
A: 使用 defaultExpanded 属性传入需要初始展开的节点 id 数组。例如 :default-expanded="['src', 'components']" 会在组件加载时自动展开这些节点。后续的展开/折叠操作会触发 update:expanded 事件。
Q: 禁用的节点在复选模式下会怎样?
A: 设置 disabled: true 的节点在复选模式下不可被勾选,其复选框会显示为禁用状态。如果父节点被禁用,其子节点仍然可以独立勾选。禁用节点不影响单选模式下的点击选中行为(单选模式不使用 disabled 属性)。