Skip to content

VirtTree API

原生版的树没有"属性 / 插槽 / 事件"三件套,只有构造函数的三个参数:

js
import { VirtTree } from '@virt-list/vanilla';
import '@virt-list/vanilla/src/tree/tree.css';

const tree = new VirtTree(container, options, events);
  • options:下方配置项渲染函数,对应框架版的属性与插槽;
  • events:下方事件回调,键名一律 camelCase(框架版模板里的 @drag-start 在这里是 dragstart);
  • 选中 / 展开 / 勾选没有 .sync 双向绑定,初值走 options,之后用暴露方法 读写,变化由 events 通知。

配置项

参数说明类型默认值是否必须
list树形数据TreeNodeData[]-
fieldNames字段名映射,见下方 TreeFieldNamesTreeFieldNames--
estimatedSize预估尺寸number32-
fixedSize是否为固定高度,可以提升性能booleanfalse-
buffer上下两侧的渲染缓冲节点数number0-
indent相邻级节点间的水平缩进,单位为像素number16-
iconSize图标大小number16-
itemGap元素之间的间距 (元素尺寸包含 itemGap)number0-
showLine是否显示层级线booleanfalse-
itemClass节点容器类名string''-
listClass列表容器类名string''-
scrollDuration平滑滚动的默认动画时长(ms)number300-
smoothMaxDistance平滑滚动允许逐帧穿越的最大距离(px),超出部分先瞬跳number两倍视口-
scrollbarAutoHideDelay滚动条停止滚动多久后淡出(ms),0 表示常驻number1200-
scrollbarMinThumbSize滑块的最小长度(px)number20-
keyboard是否接管键盘(方向键 / PageUp-Down / Space / Home-End)booleantrue-
crossScroll交叉轴(横向)是否允许原生滚动,关掉即两轴全裁切booleantrue-
[expand] expandedKeys初始展开的节点 key 集合TreeNodeKey[][]-
[expand] defaultExpandAll是否默认展开节点booleanfalse-
[expand] expandOnClickNode点击节点是否展开(仅在 selectable=false & checkOnClickNode=false 时生效;renderNode 接管整行后不生效)booleanfalse-
[checkable] checkable是否有 checkboxbooleanfalse-
[checkable] checkedKeys初始勾选的节点 key 集合,只在 checkable 为 true 时生效TreeNodeKey[][]-
[checkable] checkOnClickNode点击节点是否可以选中 checkboxbooleanfalse-
[checkable] checkedStrictly是否严格遵循父子不互相关联的做法booleanfalse-
[selectable] selectable是否可以选中(renderNode 接管整行后不生效,需自行在 click 里调 toggleSelectbooleanfalse-
[selectable] selectedKeys初始选中的节点 key 集合,只在 selectable 为 true 时生效TreeNodeKey[][]-
[selectable] selectMultiple是否可以多选booleanfalse-
[focus] focusedKeys初始激活的节点 key 集合TreeNodeKey[][]-
[draggable] draggable是否开启拖拽booleanfalse-
[draggable] dragClass拖拽的节点 classstring''-
[draggable] dragGhostClass拖拽的克隆节点 classstring''-
[draggable] dragoverPlacement拖拽区域生效的区域范围number[][33,66]-
[draggable] crossLevelDraggable是否允许跨层级拖拽;关掉则只能在同级内换位booleantrue-
customGroup同级拖拽的分组标识,同组之间才能互拖string--
filterMethod筛选节点的方法,返回 true 显示、false 隐藏(query: string, node: TreeNode) => boolean--
其他配置项同 VirtList 配置项---

渲染函数

对应框架版的插槽。返回 HTMLElement 会被 append 进容器;也可以直接操作最后一个参数 el(容器本身),少一层 DOM 嵌套。

名称说明签名
renderNode整行自定义。库不再画缩进块 / 图标 / 复选框,缩进要自己按 node.level(node, isExpanded, el) => HTMLElement | void
renderContent只替换节点内容区,缩进与图标仍由库绘制(node, el) => HTMLElement | void
renderIcon展开图标(node, isExpanded, el) => HTMLElement | void
renderHeader顶部区域(参与滚动)(el) => HTMLElement | void
renderFooter底部区域(参与滚动)(el) => HTMLElement | void
renderStickyHeader顶部悬浮区域(el) => HTMLElement | void
renderStickyFooter底部悬浮区域(el) => HTMLElement | void
renderEmpty空状态(el) => HTMLElement | void

暴露方法

实例方法,与框架版 ref 上的方法一一对应。

方法名说明签名
expandAll展开/折叠所有节点(expanded: boolean) => void
expandNode展开/折叠指定节点(key: TreeNodeKey | TreeNodeKey[], expanded: boolean) => void
toggleExpand切换节点展开状态(node: TreeNode) => void
setExpandedKeys设置展开的节点 key(keys: TreeNodeKey[]) => void
hasExpanded该节点是否展开(node: TreeNode) => boolean
selectAll全选/取消全选(selected: boolean) => void
selectNode选中/取消指定节点(key: TreeNodeKey | TreeNodeKey[], selected: boolean) => void
toggleSelect切换节点选中状态(node: TreeNode) => void
hasSelected该节点是否被选中(node: TreeNode) => boolean
checkAll全部勾选/取消勾选(checked: boolean) => void
checkNode勾选/取消指定节点(key: TreeNodeKey | TreeNodeKey[], checked: boolean) => void
toggleCheckbox切换节点勾选状态(node: TreeNode) => void
hasChecked该节点是否勾选(node: TreeNode) => boolean
hasIndeterminate该节点是否半选(node: TreeNode) => boolean
getCheckedKeys获取已勾选节点的 key(leafOnly?: boolean) => TreeNodeKey[]
getHalfCheckedKeys获取半选节点的 key() => TreeNodeKey[]
setFocusedKeys设置聚焦节点(keys: TreeNodeKey[]) => void
hasFocused该节点是否聚焦(node: TreeNode) => boolean
filter按查询字符串筛选节点(query: string) => void
scrollTo滚动到(三种意图合一,见下方 VirtTreeScrollTarget(target: VirtTreeScrollTarget) => void
scrollToKey定位到指定节点(折叠时先展开祖先),无论当前是否可见(key: TreeNodeKey, options?: VirtScrollOptions) => void
scrollKeyIntoView把节点滚进可视区域,已完整可见则不动(key: TreeNodeKey, options?: VirtScrollOptions) => void
scrollToOffset滚动到指定偏移量(offset: number, options?: VirtScrollOptions) => void
scrollToTop滚动到顶部(options?: VirtScrollOptions) => void
scrollToBottom滚动到底部(options?: VirtScrollOptions) => void
scrollFromUser上报一次用户发起的滚动(offset: number) => void
cancelScroll取消进行中的平滑滚动动画() => void
resume重挂 DOM 后把内容摆回当前偏移量() => void
getOffset当前偏移量() => number
getMaxOffset当前允许的最大偏移量() => number
getTotalSize内容总尺寸(节点 + 各插槽)() => number
getTreeNode根据 key 获取节点(key: TreeNodeKey) => TreeNode | undefined
setList设置新的树数据(list: TreeData) => void
updateOptions增量更新配置项(options: Partial<VirtTreeDOMOptions>) => void
forceUpdate强制更新() => void
destroy销毁实例并解绑所有监听() => void

事件回调

构造函数的第三个参数。键名一律 camelCase。

树相关

事件名说明回调参数
click点击节点(内容区;renderNode 接管后为整行)。与 select / check / 展开互不冲突,先于它们触发,拖拽进行中不触发(data: TreeNodeData, node: TreeNode, e: MouseEvent)
expand展开/折叠节点expandKeys: TreeNodeKey[]data{ node?: TreeNode; expanded: boolean; expandedNodes: TreeNodeData[] }
select选择节点selectedKeys: TreeNodeKey[]data{ node: TreeNode; selected: boolean; selectedKeys: TreeNodeKey[]; selectedNodes: TreeNodeData[] }
check勾选节点checkedKeys: TreeNodeKey[]data{ node: TreeNode; checked: boolean; checkedKeys: TreeNodeKey[]; checkedNodes: TreeNodeData[]; halfCheckedKeys: TreeNodeKey[]; halfCheckedNodes: TreeNodeData[] }
dragstart拖拽开始。sourceNode 是树节点,原始数据在它的 .datadata{ sourceNode: TreeNode }
dragend拖拽结束。参数为 undefined 表示被取消(Esc)data{ node: TreeNode; prevNode: TreeNode | undefined; parentNode: TreeNode | undefined } | undefined

滚动相关(由 VirtList 透传)

事件名说明回调参数
scroll滚动(event: VirtScrollEvent)
offsetChange偏移量变化(offset: number)
toTop触顶(item: TreeNode)
toBottom触底(item: TreeNode)
itemResizeItem 尺寸变化(id: string, size: number)
update渲染列表更新(renderList: TreeNode[], state: ListState)

TreeNode

参数名描述类型默认值
key唯一标示string | number-
level层级number1
title该节点显示的标题string-
isLeaf是否是叶子节点。动态加载时有效booleanfalse
isLast是否是当前层级的最后节点booleanfalse
parent父节点引用TreeNode-
children子节点TreeNode[]-
disableSelect是否禁用选中booleanfalse
disableCheckbox是否禁用复选框booleanfalse
searchedIndex筛选匹配下标(-1 表示未匹配)number-1
data原始数据对象 TreeNodeDataTreeNodeData-

TreeFieldNames

AttributeDescriptionTypeDefaultRequired
key每个树节点用来作为唯一key的属性string, numberkey-
title指定节点标签为节点对象的某个属性值stringtitle-
children指定子树为节点对象的某个属性值stringchildren-
disableSelect禁止选中stringdisableSelect-
disableCheckbox禁止复选框勾选stringdisableCheckbox-
disableDragIn禁止拖入该节点stringdisableDragIn-
disableDragOut禁止拖出该节点stringdisableDragOut-

VirtTreeScrollTarget

scrollTo 的参数。它在 VirtScrollOptions 的基础上加了 key / offset,并把 align 扩出一个 nearest

AttributeDescriptionTypeDefault
key目标节点 key。节点被折叠时会先展开它的祖先TreeNodeKey-
offset偏移量(≥ 0 时优先于 keynumber-
align对齐方式。nearest:已完整可见就不动,否则滚到最近的那条边;start:顶部对齐视口顶部;end:底部对齐视口底部'start' | 'end' | 'nearest'nearest
behavior滚动方式,smooth 为平滑动画'auto' | 'smooth'auto
duration平滑动画时长(ms),缺省取 scrollDurationnumber-
maxDistance本次逐帧穿越的最大距离(px),超出部分先瞬跳number两倍视口
onDone动画结束回调,canceled 表示被中断(canceled: boolean) => void-

通常用直接方法更好读

scrollTo 把三种意图收在一个入口里,拼参数往往不如直接调用清楚: scrollToOffset(offset, options?) / scrollToKey(key, options?) / scrollKeyIntoView(key, options?)。三者的 options 都是标准的 VirtScrollOptionsalign 只有 start / end

样式与主题

树组件的默认样式随各包的 style.css 一起交付,需要手动引一次(与滚动条样式同一份):

ts
import '@virt-list/vue/style.css'; // 换成你装的那个包

组件的 JS 里刻意不 import 这份 css:那会让整个包在纯 Node 环境(SSR)下 import 不了 ——Node 不认 .css 扩展名。

所有可定制项都通过 CSS 变量暴露,覆盖变量即可换肤,不需要与选择器优先级搏斗。

暗色模式

样式内置两套令牌,命中以下任一条件即切换为暗色:

  • <html> 上带有 dark class(VitePress、大多数文档站与后台框架的约定);
  • 任意祖先元素上带有 data-theme="dark"
ts
// 自行控制时,只需切换根节点的 class
document.documentElement.classList.toggle('dark', isDark);

如果你的项目使用别的主题标记(例如 body[theme='night']),直接在该选择器下覆盖变量即可:

css
body[theme='night'] .virt-tree-item {
  --virt-tree-color-text: rgb(255 255 255 / 87%);
  --virt-tree-color-node-bg-hover: rgb(235 235 245 / 8%);
  --virt-tree-line-color: #3c3f46;
}

可用变量

变量定义在 .virt-tree-item.virt-tree-all-drag-area 上,覆盖时请使用同一层级或更高优先级的选择器。

变量说明亮色默认值暗色默认值
--virt-tree-color-text节点文字#1f2329rgb(255 255 255 / 87%)
--virt-tree-color-text-selected选中态文字#1f52d6#8fb2ff
--virt-tree-color-text-disabled禁用态文字#a8abb2rgb(235 235 245 / 38%)
--virt-tree-color-node-bg节点背景(默认透明,跟随容器)transparenttransparent
--virt-tree-color-node-bg-hover悬停背景rgb(31 35 41 / 6%)rgb(235 235 245 / 8%)
--virt-tree-color-node-bg-selected选中背景rgb(42 99 240 / 10%)rgb(97 143 250 / 20%)
--virt-tree-color-node-bg-disabled禁用背景transparenttransparent
--virt-tree-color-node-bg-focused聚焦背景rgb(42 99 240 / 6%)rgb(97 143 250 / 10%)
--virt-tree-color-node-ring-focused聚焦描边环rgb(42 99 240 / 55%)rgb(140 175 255 / 65%)
--virt-tree-color-icon展开箭头颜色#5f6672rgb(235 235 245 / 60%)
--virt-tree-color-icon-bg-hover展开箭头悬停底色rgb(31 35 41 / 10%)rgb(235 235 245 / 14%)
--virt-tree-line-color层级连接线#d6d9dd#3c3f46
--virt-tree-color-checkbox-bg复选框底色#ffftransparent
--virt-tree-color-checkbox-bg-checked勾选底色#2a63f0#3970e4
--virt-tree-color-checkbox-bg-indeterminate半选底色#2a63f0#3970e4
--virt-tree-color-checkbox-bg-disabled禁用底色#f2f3f5rgb(235 235 245 / 8%)
--virt-tree-color-checkbox-border复选框描边#c4c7ce#55575e
--virt-tree-color-checkbox-border-hover复选框悬停描边#2a63f0#5a8dfb
--virt-tree-color-checkbox-border-checked勾选描边#2a63f0#3970e4
--virt-tree-color-checkbox-border-indeterminate半选描边#2a63f0#3970e4
--virt-tree-color-checkbox-border-disabled禁用描边#dcdfe4#3a3b41
--virt-tree-color-checkbox-mark勾/横杠颜色#fff#fff
--virt-tree-color-drag-line拖拽指示线#2a63f0#5a8dfb
--virt-tree-color-drag-box拖入节点内的高亮框底色rgb(42 99 240 / 8%)rgb(97 143 250 / 14%)
--virt-tree-color-drag-line-disabled不可放置时的指示线rgb(42 99 240 / 40%)rgb(97 143 250 / 40%)
--virt-tree-color-allow-drag-area-bg可放置区域底色rgb(42 99 240 / 8%)rgb(97 143 250 / 12%)
--virt-tree-color-allow-drag-area-bd可放置区域描边rgb(42 99 240 / 45%)rgb(97 143 250 / 50%)
--virt-tree-color-bg-clone-node拖拽跟随副本底色#fff#26272d
--virt-tree-node-radius节点圆角6px同亮色
--virt-tree-icon-radius箭头悬停底色圆角4px同亮色
--virt-tree-checkbox-size复选框尺寸16px同亮色
--virt-tree-checkbox-radius复选框圆角4px同亮色
--virt-tree-duration过渡时长160ms同亮色
--virt-tree-ease过渡曲线cubic-bezier(0.4, 0, 0.2, 1)同亮色
--virt-tree-switcher-icon-margin-right箭头右间距(同时影响拖拽线左偏移)4px同亮色
--virt-tree-drag-line-gap跨层级拖拽线的分段间隔4px同亮色

状态 class

库会在节点上切换以下 class,可直接用于自定义样式:

class元素含义
is-selected.virt-tree-node已选中
is-focused.virt-tree-node已聚焦
is-disabled.virt-tree-node禁止选中
is-expanded.virt-tree-icon-wrapper已展开
is-checked.virt-tree-checkbox已勾选
is-indeterminate.virt-tree-checkbox半选
is-dragging.virt-list__client拖拽进行中
css
/* 例:换成品牌绿,并放大节点圆角 */
.virt-tree-item {
  --virt-tree-color-text-selected: #12854a;
  --virt-tree-color-node-bg-selected: rgb(24 160 88 / 12%);
  --virt-tree-color-checkbox-bg-checked: #18a058;
  --virt-tree-color-checkbox-border-checked: #18a058;
  --virt-tree-node-radius: 10px;
}

减少动效

样式已适配 prefers-reduced-motion: reduce,系统开启「减弱动态效果」时会自动关闭箭头旋转、勾选与背景过渡动画。