Tree

树形控件(严格对齐 Semi):层级展示节点,支持展开/收起、单选/多选(multiple 驱动 checkbox 父子联动含半选 mixed)、内置搜索高亮。值通道统一走 value/onChange。受控 value/expandedKeys 均不回写,仅通过 onChange/onExpand/onSelect/onSearch 通知。键盘导航遵循 WAI-ARIA APG Tree View(单一 tab stop + aria-activedescendant)。

设计文档

如何引入

import { Tree } from '@chenzy-design/svelte';

基础用法

默认单选,每级菜单项均可选择。

亚洲
中国
北京
上海
日本
大阪
北美洲
美国
加拿大
已选:beijing

多选

multiple + checkable:子项全选自动勾选父项,部分选中显半选。

亚洲
中国
北京
上海
日本
大阪
北美洲
美国
加拿大
已勾选 0 项

可搜索

filterTreeNode 开启搜索,命中高亮 + 自动展开祖先;showFilteredOnly 只展示命中结果。

亚洲
中国
北京
上海
日本
大阪
北美洲
美国
加拿大

自定义搜索框

searchRender 自定义搜索框渲染(复用 Input 组件)。

亚洲
中国
北京
日本
北美洲
美国

手动触发搜索

searchRender={false} 隐藏内置框,经组件实例 search() 由外部输入驱动。

亚洲
中国
北京
日本
北美洲
美国

简单 JSON 数据

treeDataSimpleJson 传入扁平键值对,自动转为树。

亚洲
中国
北京
上海
日本
北美洲
美国
加拿大

行显示节点

blockNode(默认 true)整行高亮;false 时仅高亮 label。

blockNode(默认 true):整行高亮
亚洲
中国
日本
北美洲
美国
blockNode=false:仅高亮 label
亚洲
中国
日本
北美洲
美国

自定义节点内容

renderLabel snippet 自定义节点渲染(父节点加计数标签)。

前端团队
2 人
张三
李四
后端团队
1 人
王五

自定义图标

icon snippet 按叶子/展开态渲染文件夹与文件图标。

文档
入门指南
API 参考
资源

目录树模式

directory:整行块 + 内置目录/文件图标 + 点击整行展开。

src
components
Tree.svelte
Input.svelte
index.ts
public
favicon.ico

禁用

disableStrictly:禁用节点勾选态不受父/子联动改变。

disableStrictly:禁用节点勾选态被锁定,非禁用节点仍可正常勾选
亚洲
中国
北京
上海(禁用)
日本(禁用)
已勾选 1 项

节点选中关系

checkRelation 'related'(联动+半选)与 'unRelated'(互不影响)。

related(默认):父子联动 + 半选
亚洲
中国
日本
北美洲
美国
unRelated:父子互不影响、无半选
亚洲
中国
日本
北美洲
美国

默认展开

defaultExpandAll 仅初始化生效;expandAll 数据更新后仍生效。

defaultExpandAll 追加后不再展开新节点;expandAll 追加后仍自动展开
defaultExpandAll
节点 1
节点 1-1
expandAll
节点 1
节点 1-1

受控

expandedKeys / value 受控,外部按钮控制展开与选中。

亚洲
日本
已选:(未选)

自动展开父节点

autoExpandParent:仅指定叶子也会展开其祖先链。

autoExpandParent:需先收起「中国」才能收起「亚洲」
亚洲
中国
北京

自定义展开图标

expandIcon snippet 自定义展开/收起箭头(+/− 号)。

亚洲
+ 中国
+ 日本
北美洲
+ 美国

连接线

showLine 显示节点之间的层级连接线(├ / └ / 竖线)。

亚洲
中国
北京
上海
日本
大阪
北美洲
美国

虚拟化

1050 节点仅渲染视口内行;scrollTo() 滚动到指定节点。

分组 1
分组 1 · 节点 1
分组 1 · 节点 2
分组 1 · 节点 3
分组 1 · 节点 4
分组 1 · 节点 5
分组 1 · 节点 6
分组 1 · 节点 7
分组 1 · 节点 8
分组 1 · 节点 9
分组 1 · 节点 10
分组 1 · 节点 11
分组 1 · 节点 12
分组 1 · 节点 13

异步加载

loadData 展开时动态拉取子节点,叶子需标 isLeaf。

香港(叶子)

动态更新数据

切换数据集,expandAll 保持全展开。

数据集 A
A-1
A-2

可拖拽

draggable + onDrop 实现节点拖拽排序(before / inside / after)。

draggable:拖拽节点改变层级/顺序(before / inside / after)
一级 A
A-1
A-2
一级 B
B-1
一级 C
最近一次:(未拖拽)

高级定制·叶子分组勾选

renderFullLabel 只在叶子渲染勾选框,父节点仅分组(leafOnly)。

亚洲
中国
北京
上海
日本
大阪

高级定制·单选高亮子节点

renderFullLabel + onSelect:选中父节点同时高亮其子孙。

模块
自由摆放组件
分栏容器
按钮组件
文本组件

字段映射

keyMaps 把后端 id/name/sub 映射为标准字段。

设计中心
Figma 规范
Design Token
研发中心
前端组
已选:(未选)

自定义搜索谓词

filterTreeNode 传函数自定义命中逻辑(按 label 前缀),命中节点祖先链自动展开。

Asia
China
Beijing
Shanghai
Japan
Osaka
North America
United States
Canada

开启搜索的展开受控

受控 expandedKeys 时搜索不自动展开,用 onSearch 的 filteredKeys 回写展开集。

北美洲

可拖拽的高级定制

draggable + renderFullLabel 同用:整行自定义 + 拖拽排序 + 选中高亮子孙。

黑色固定按钮
模块
可自由摆放的组件
分栏容器
按钮组件
按钮组件
模块
自定义组件

API 参考

Tree

Props

属性说明类型默认值
treeData树数据源;字段名可经 keyMaps 自定义TreeNodeData[][]
treeDataSimpleJson简单 JSON 形式的树数据(对齐 Semi):扁平 { key: value } 键值对,key 同时作 key/label,value 作节点 value,嵌套对象转子树。treeData 非空时优先,忽略此项Record<string, unknown>undefined
keyMaps自定义节点字段名映射(对齐 Semi keyMaps),适配任意后端数据(如 { key:'id', label:'name', children:'sub' })。派生只读映射,回调回传原始节点{ key?: string; label?: string; children?: string }{ key:'key', label:'label', children:'children' }
value受控选中值(对齐 Semi value);单选为标量、multiple 时为选中 key 数组(含父子联动结果)。onChangeWithObject 时为节点对象形态。受控时不回写TreeKey | TreeNodeData | Array<TreeKey | TreeNodeData> | nullundefined
defaultValue非受控初始选中值;形态同 valueTreeKey | TreeNodeData | Array<TreeKey | TreeNodeData> | nullnull
onChangeWithObject以对象形态收发选中项:开启后 onChange 的 value 及受控 value/defaultValue 均为节点对象(含 label/value/其它字段),对象标识优先取 key 缺省回退 valuebooleanfalse
multiple多选模式(对齐 Semi multiple):开启渲染 checkbox + 父子联动,值经 value/onChange 收发booleanfalse
disableStrictly严格禁用:disabled 节点勾选态被锁定,不能通过父/子级联动改变(区别于普通 disabled 仅禁直接点击)。仅 multiple 联动下有意义booleanfalse
leafOnly多选时 onChange 回传的 value 只含叶子节点 key(滤掉父/半选节点)booleanfalse
checkRelation多选父子勾选联动关系(对齐 Semi)。'related'(默认)联动含半选;'unRelated' 父子独立无半选'related' | 'unRelated''related'
expandedKeys受控展开。受控时不回写TreeKey[]undefined
defaultExpandedKeys非受控初始展开TreeKey[][]
defaultExpandAll初始展开全部booleanfalse
autoExpandParent自动展开父节点(对齐 Semi 默认 false):初次挂载时把初始展开节点的祖先链并入;开启后收起父节点需先收起其展开的子节点booleanfalse
expandAction展开触发方式:false 仅点箭头;'click' 点整行展开;'doubleClick' 双击整行展开(箭头任意模式可点)false | 'click' | 'doubleClick'false
autoMergeValue多选 value 自动合并父子:父节点完全选中时 onChange 回传只保留父不含子孙。仅 multiple 联动且 leafOnly=false 时有意义booleantrue
labelEllipsislabel 超长单行省略;未显式传时跟随虚拟化booleanfalse(virtualize 时 true)
preventScroll组件内 focus() 时是否阻止浏览器滚动文档(作用于导出的命令式 focus 方法)booleanfalse
showLine显示层级连接线(├/└/竖线,对齐 Semi showLine)booleanfalse
virtualize列表虚拟化(对齐 Semi virtualize):传对象即开启,itemSize(行高 px)必传;仅渲染视口内可见行,适合大数据树;开启强制关闭动画{ itemSize: number; height?: number | string; width?: number | string }undefined
filterTreeNode是否根据输入项筛选(对齐 Semi):true 用内置谓词(按 treeNodeFilterProp 字段包含匹配),传函数自定义命中逻辑;命中节点祖先链自动展开boolean | ((input: string, node: TreeNodeData) => boolean)false
treeNodeFilterProp内置搜索匹配节点的哪个字段(仅内置谓词生效,传自定义谓词时由函数决定)string'label'
searchStyle搜索框内联样式(透传到 input style)stringundefined
searchClassName搜索框附加 class(追加到 input)stringundefined
showClear搜索框有内容时显示清除按钮,点击清空(对齐 Semi showClear)booleantrue
showFilteredOnly搜索状态下只渲染命中节点及其祖先链,隐藏其它未命中节点(默认 false 展示全树、命中高亮、祖先自动展开)booleanfalse
blockNode整行点击选中(对齐 Semi 默认 true;directory 时强制整行)booleantrue
directory目录树模式:整行块 + 内置目录/文件图标 + 默认点击整行展开booleanfalse
motion展开/收起动画开关;virtualized 时强制关闭booleantrue
expandAll展开全部:数据变化时仍生效(区别于仅初始化的 defaultExpandAll);仅非受控展开有意义booleanfalse
loadedKeys受控已加载节点 key,配合 loadData;已加载节点展开时不再触发 loadDataTreeKey[]undefined
style根容器内联样式(对齐 Semi style);设 height 时列表区限高滚动stringundefined
class根元素自定义类名(对齐 Semi className)stringundefined
searchPlaceholder搜索框占位文案(不传用内置 i18n)stringundefined
searchRender自定义搜索框渲染;传 false 隐藏内置搜索框(仍可经 search() 方法驱动)false | Snippet<[SearchRenderContext]>undefined
onSelect节点选中回调(早于 onChange)(key, selected, node) => voidundefined
onDragOver拖拽悬停在候选目标上(info) => voidundefined
onDragLeave拖拽离开候选目标(info) => voidundefined
onDragEnd拖拽结束(无论是否成功放下)(info) => voidundefined
renderFullLabel完全接管整行渲染(叶子分组勾选、单选高亮子节点等高级场景)Snippet<[FullLabelContext]>undefined
disabled整树禁用booleanfalse
emptyContent空态文案stringundefined
ariaLabel无障碍标签stringundefined
loadData异步加载子节点:展开未加载的非叶子节点时调用(node) => Promise<TreeNodeData[]>undefined
onLoad异步加载完成回调(loadedKeys: string[], info: { event: 'load'; node: TreeNodeData }) => voidundefined
draggable启用 HTML5 拖拽排序:节点可拖动改变层级/顺序(before/inside/after)booleanfalse
autoExpandWhenDragEnter拖拽到节点内部(inside)时是否延时自动展开该节点。仅 draggable 时有意义booleantrue
hideDraggingNode是否隐藏拖拽跟随的 dragImg(设透明 drag image)。仅 draggable 时有意义booleanfalse
renderDraggingNode自定义拖拽 dragImg 元素,优先级高于 hideDraggingNode。仅 draggable 时有意义(nodeInstance: HTMLElement, node: TreeNodeData) => HTMLElementundefined
onDoubleClick节点双击回调(e: MouseEvent, node: TreeNodeData) => voidundefined
onDrop放下时回调;受控数据由父组件按 info 重排 treeData,组件不内部改(info: { dragNode, dropNode, dropPosition }) => voidundefined
onDragStart开始拖拽节点(node: TreeNodeData) => voidundefined
onDragEnter拖拽进入候选目标节点(info: { dragNode: TreeNodeData; dropNode: TreeNodeData }) => voidundefined
onContextMenu节点右键菜单回调(对齐 Semi onContextMenu)(e: MouseEvent, node: TreeNodeData) => voidundefined
onSearch搜索关键词变化回调(对齐 Semi);第二参为因搜索而展开的祖先链 key(value: string, filteredExpandedKeys: string[]) => voidundefined
onChange选中变更(对齐 Semi):单选回 key,多选回选中 key 数组(value) => voidundefined
onExpand展开/收起回调(对齐 Semi onExpand)(expandedKeys, { expanded, node }) => voidundefined
renderLabel自定义节点内容(对齐 Semi renderLabel)Snippetundefined
icon自定义节点图标(对齐 Semi icon;传入时渲染在 label 前)Snippet<[{ node, expanded, isLeaf }]>undefined
expandIcon自定义展开/收起图标(对齐 Semi expandIcon);参数含节点、展开态与加载态Snippet<[{ node: TreeNodeData; expanded: boolean; loading: boolean }]>undefined
suffix节点尾部操作区(渲染在 label 右侧)Snippet<[{ node: TreeNodeData }]>undefined
dragGhost自定义拖拽幽灵节点Snippet<[{ node: TreeNodeData }]>undefined

Events

事件载荷说明
onChange选中变更:单选回选中 key(或节点对象),多选回选中 key 数组
onSelect单个节点选中:(key, selected, node),早于 onChange
onExpand展开/收起:(expandedKeys, { expanded, node })
onDrop拖拽放下:{ dragNode, dropNode, dropPosition: before|inside|after }

Slots

名称说明
renderLabel自定义节点内容渲染:{ node, level, searchValue, selected, checked }
renderFullLabel整行接管渲染:FullLabelContext(data/level/style/className/expandIcon/checkStatus/expandStatus/onClick/onCheck/onExpand…)
searchRender自定义搜索框:SearchRenderContext(value/placeholder/onChange/onClear/showClear/disabled)
icon自定义节点图标:{ node, expanded, isLeaf }
expandIcon自定义展开图标:{ node, expanded, loading }
suffix节点尾部操作区:{ node }

Methods

属性类型说明
focus命令式聚焦树容器(尊重 preventScroll)
search命令式触发搜索(对齐 Semi):(value: string) => void,配合 searchRender=false
scrollTo虚拟化滚动到节点(对齐 Semi):({ key, align? }) => void

Accessibility

  • role=tree(aria-multiselectable=multiple)容器为单一 tab stop,焦点通过 aria-activedescendant 指向当前高亮 treeitem;每行 role=treeitem 含 aria-level/setsize/posinset/expanded/disabled,单选时 aria-selected、多选时 aria-checked 支持 true/false/"mixed"(半选)。方向键导航:↑↓ 移动、→ 展开/进入子、← 折叠/回父、Home/End 首末、Enter 选中、Space 勾选或选中。

设计变量

变量默认值用法
--cd-color-tree-option-bg-active var(--cd-color-primary-light-default)树选项选中/激活背景($color-tree_option-bg-active)
--cd-color-tree-option-bg-hover var(--cd-color-fill-0)树选项悬停背景($color-tree_option-bg-hover)
--cd-color-tree-option-disabled-text-default var(--cd-color-disabled-text)禁用树选项文字颜色($color-tree_option_disabled-text-default)
--cd-color-tree-option-draggable-insert-border-default var(--cd-color-primary)可拖拽插入指示线颜色($color-tree_option_draggable_insert-border-default)
--cd-color-tree-option-highlight-text var(--cd-color-primary)搜索命中高亮文本色($color-tree_option_hightlight-text)
--cd-color-tree-option-icon-active var(--cd-color-black)展开图标按下色($color-tree_option-icon-active)
--cd-color-tree-option-icon-default var(--cd-color-text-2)展开箭头 / 节点图标颜色($color-tree_option-icon-default)
--cd-color-tree-option-icon-hover var(--cd-color-text-0)展开图标悬停色($color-tree_option-icon-hover)
--cd-color-tree-option-line var(--cd-color-text-3)showLine 连接线颜色(Semi 用 --semi-color-text-3)
--cd-color-tree-option-loading-icon-default var(--cd-color-primary)树选项加载 spin 颜色($color-tree_option_loading-icon-default)