DirectSurface UIDirectSurface UI
开始使用
文档/组件手册

TreeView 树组件

通用布局能力RenderTreeView 实例统一支持 widthheight、min/max、margin 和槽位对齐;原有独立高度状态已经并入 RenderBox 契约。详见组件通用布局属性

LIVE CANVAS可运行组件示例
ON-DEMAND RUNTIME交互式示例将在进入视区时启动避免文档首屏同时初始化多个 Canvas Runtime

RenderTreeView 用于展示单列层级数据,支持展开折叠、单选、复选、半选、虚拟滚动、键盘导航、复制、文本省略和 tooltip。它适合导航树、目录树、分类树、模板树、对象结构浏览等场景。

何时使用

  • 左侧导航树、文档目录、分类目录、组织结构。
  • 只需要显示一个主 label,可附带 icon、tooltip 或 label token 着色。
  • 需要节点单选或勾选,并支持父子半选。
  • 需要大树虚拟滚动。
  • 需要复制当前选中节点文本。

何时不要使用

  • 每个节点需要显示多列字段,使用 TreeGrid
  • 没有层级结构,只是普通列表,使用 ListView
  • 需要弹出树形选择,使用 DropTreeEdit
  • 需要弹出树形多选,使用 DropCheckTreeEdit
  • 需要查看任意对象属性树,优先使用 ObjectInspector 相关组件,而不是业务层手写 TreeView。

API 总览

import {  RenderTreeView,  type TreeCheckChange,  type TreeLabelToken,  type TreeLabelTokenKind,  type TreeNode,  type TreeSelectionMode,} from 'ds-ui'
API 类型 用途
RenderTreeView<T> class 单列层级树,支持展开折叠、单选、复选、半选、虚拟滚动和复制。
TreeNode<T> type 树节点配置,保存稳定 key、label、children 和业务 data。
TreeSelectionMode type 选择模式:singlecheck
TreeCheckChange<T> type 勾选变化回调 payload。
TreeLabelToken type 分段着色 label token。
TreeLabelTokenKind type label token 语义类型。

最小装配顺序是:准备稳定 key 的 TreeNode<T>[],创建 RenderTreeView({ roots }),再按需配置选择、勾选、展开和回调。业务代码应只从 ds-ui 包入口导入这些类型,不要从 src/widgets/tree 等内部路径导入。

最小示例

import { RenderTreeView, type TreeNode } from 'ds-ui' interface DocEntry {  path: string} const docTreeRoots: TreeNode<DocEntry>[] = [  {    key: 'guide',    label: '开发指南',    icon: '📁',    children: [      { key: 'quick-start', label: '快速开始', data: { path: 'quick-start.md' } },    ],  },] const docTree = new RenderTreeView<DocEntry>({  roots: docTreeRoots,  defaultExpandedKeys: ['guide'],  onSelect: node => {    console.log(node.key, node.data?.path)  },})

构造参数

new RenderTreeView<T>(opts)

参数 类型 默认值 说明
roots TreeNode<T>[] 必填 根节点数组。
selectionMode 'single' | 'check' 'single' 选择模式。
checkedKeys readonly string[] undefined 受控或初始化勾选 key。优先级高于 defaultCheckedKeys
defaultCheckedKeys readonly string[] [] 非受控初始勾选 key。
defaultExpandedKeys string[] [] 初始展开节点 key。
width / height number undefined 来自 RenderBoxOptions 的期望尺寸。
minWidth / maxWidth number undefined 水平方向尺寸边界。
minHeight / maxHeight number undefined 垂直方向尺寸边界。
margin EdgeInsetsInput 0 组件外部留白。
horizontalAlignment / verticalAlignment BoxAlignment undefined 组件在父布局槽位中的对齐方式。
disabled boolean false 整体禁用。禁用后不进入焦点顺序,不响应鼠标、键盘、滚轮和复制。
onSelect (node) => void undefined 节点被单选选中后触发。
onExpand (node, expanded) => void undefined 节点展开或折叠后触发。
onActivate (node) => void undefined 节点被激活后触发。
onCheck (payload) => void undefined 勾选状态变化后触发。
copyable boolean true 是否允许复制当前节点。
copyText (node) => string | null | undefined undefined 自定义复制文本。

节点配置

TreeNode<T>

字段 类型 默认值 说明
key string 必填 节点唯一 key。展开、选中、勾选、定位都依赖它。
label string 必填 主显示文本。
labelTokens readonly TreeLabelToken[] undefined 分段着色文本。存在时优先按 token 绘制。
tooltip string undefined 节点 tooltip。未设置时,文本被省略才使用完整 label 作为 tooltip。
icon string undefined 轻量图标,通常使用 emoji 或单字符图标。
selectable boolean true 是否允许单选选中。false 的父节点点击时会优先展开折叠。
checkable boolean true 是否允许复选。false 的节点不会作为勾选目标。
data T undefined 业务数据。组件不解析它,只在回调中原样返回。
children TreeNode<T>[] undefined 子节点。存在子节点时显示展开箭头。

TreeLabelToken

字段 类型 说明
text string 当前分段文本。
kind TreeLabelTokenKind 分段语义,用于主题决定颜色。

labelTokens 适合 ObjectInspector、搜索结果、语法着色等场景。普通树只使用 label 即可。

TreeLabelTokenKind 当前支持:

  • key:对象 key、字段名或路径片段。
  • string:字符串值。
  • number:数字值。
  • boolean:布尔值。
  • null:空值。
  • type:类型说明。
  • punctuation:括号、逗号、冒号等结构符号。
  • muted:弱化说明文本。
  • warning:警告文本。
  • error:错误文本。
  • match:搜索命中文本。

可读写属性

属性 类型 说明
selectionMode TreeSelectionMode 当前选择模式。
roots TreeNode<T>[] 根节点数组。替换或重新设置会重建扁平节点和勾选状态。
indentWidth number 只读。当前缩进宽度,由主题字体尺寸决定。
expandedKeys string[] 展开的节点 key。设置后会重建扁平节点。
selectedKey string 当前选中节点 key。设置后会在下一次布局时滚动到该节点。
checkedKeys string[] 当前勾选的叶子目标 key。设置后会重新计算全选和半选。
halfCheckedKeys string[] 只读。当前半选 key。
disabled boolean 整体禁用状态。动态设置为 true 会退出焦点、清理 hover/focused/scrollbar dragging 和 tooltip,并请求重绘。
width / height number | undefined 期望尺寸。赋值后请求 layout。
minWidth / maxWidth number | undefined 水平方向尺寸边界。赋值后请求 layout。
minHeight / maxHeight number | undefined 垂直方向尺寸边界。赋值后请求 layout。
margin EdgeInsets 组件外部留白。赋值后请求 layout。
horizontalAlignment / verticalAlignment BoxAlignment | undefined 组件在父布局槽位中的对齐方式。
isFocused boolean 只读。当前是否持有焦点。

方法

方法 返回值 说明
focusIn() void 通知组件获得焦点。整体 disabled 或 invisible 时不生效。
focusOut() void 通知组件失去焦点。
getCopyText() string | null 获取当前选中节点或焦点节点的复制文本。整体 disabled 或 copyable=false 时返回 null。
debugState() 对象 获取滚动、焦点、hover、内容高度、行高、缩进、勾选状态。
revealSelectedKey() void 将当前 selectedKey 对应节点滚动到可视区域。
setRoots(roots) void 替换根节点。等价于设置 roots 属性。
expandAll() void 展开所有有子节点的节点。
collapseAll() void 折叠全部节点。
dispose() void 释放焦点注册、滚动状态和回调引用。

debugState() 返回字段:

字段 说明
scrollY 当前纵向滚动偏移。
focusedIndex 当前键盘焦点行索引。
hoveredKey 当前 hover 节点 key。
totalContentH 全部扁平节点总高度。
rowHeight 当前行高。
indentWidth 当前缩进宽度。
checkedKeys 当前勾选 key。
halfCheckedKeys 当前半选 key。

事件与回调

回调 触发时机 参数说明
onSelect(node) 单选模式下节点被选中 selectable=false 的节点不会触发。
onExpand(node, expanded) 节点展开或折叠后 expanded=true 表示展开。
onActivate(node) 节点被激活后 当前实现主要由 Enter 触发。
onCheck(payload) 勾选状态变化后 payload 包含勾选、半选的 key 和节点。

TreeCheckChange<T>

字段 说明
checkedKeys 当前勾选 key。
halfCheckedKeys 当前半选 key。
checkedNodes 当前勾选节点。
halfCheckedNodes 当前半选节点。
toggledNode 本次被切换的节点。

单选和勾选模型

selectionMode='single'

  • 点击可选择节点会更新 selectedKey 并触发 onSelect
  • 点击展开箭头只展开折叠,不改变选择。
  • selectable=false 的父节点点击时会展开折叠。
  • Space 可选择当前焦点节点。
  • Enter 触发 onActivate

selectionMode='check'

  • 行内显示复选框。
  • 点击复选框或按 Space 切换勾选。
  • 勾选父节点会切换它下面的可勾选叶子目标。
  • 子节点部分勾选时,父节点进入半选状态。
  • checkable=false 的节点不会作为勾选目标。

键盘、鼠标和滚动

  • ArrowDown / ArrowUp:移动焦点行。
  • ArrowRight:展开当前节点;如果已展开,则移动到第一个子节点。
  • ArrowLeft:折叠当前节点;如果已折叠,则移动到父节点。
  • Space:单选模式下选中当前节点;复选模式下切换勾选。
  • Enter:激活当前节点。
  • 鼠标点击节点行会设置焦点。
  • 鼠标点击展开箭头会展开或折叠。
  • 鼠标滚轮按固定步长滚动,滚到底部或顶部后返回是否仍可滚动,便于外层滚动容器判断是否接管。
  • 拖动垂直滚动条会更新 scrollY 并触发重绘。
  • 整体 disabled = true 时,树不会接收焦点,不响应选择、勾选、展开、激活、滚轮、滚动条拖动或复制。

文本省略和 tooltip

TreeView 会按可用宽度绘制单行文本:

  • 文本能完整显示时,不自动设置 tooltip。
  • 文本被省略时,如果节点设置了 tooltip,显示 tooltip
  • 文本被省略且未设置 tooltip 时,显示完整 label
  • 使用 labelTokens 时,tooltip 仍以 tooltiplabel 为准。

这适合文档目录、对象查看器、模板树等长文本场景。

虚拟滚动和大树

TreeView 会把当前展开状态下的节点扁平化为可视节点列表,然后使用固定行高虚拟范围计算,只绘制视窗附近的节点。

性能边界:

  • 替换 roots 会重建扁平节点、勾选状态和滚动约束。
  • expandAll() 会一次性展开所有节点,大树上会显著增加扁平节点数量。
  • 大树场景不要在 hover、滚动、输入时反复创建新的 roots 数组。
  • 异步加载子节点后,优先局部更新业务节点,再调用 setRoots() 或设置 roots 触发同步。
  • 节点 key 必须稳定,否则展开、选中、勾选状态无法延续。

常见组合

  • TreeView + MarkdownViewer:左侧文档树,右侧 MarkdownViewer
  • TreeView + 详情面板:选中节点后右侧显示表单、图表或 GridView
  • TreeView + DropTreeEdit:维护页面使用 TreeView,表单选择使用 DropTreeEdit
  • TreeView + TreeGrid:单列树用 TreeView,多列树用 TreeGrid
  • TreeView + ObjectInspector:对象查看器可复用树的展开、虚拟滚动和复制思路,但业务不应直接把 ObjectInspector 写成普通 TreeView 示例。

相关组件