Tree
用于展示层级数据并支持展开、选择和虚拟滚动的树组件
Tree 用于展示文件目录、组织结构、分类层级等嵌套数据。组件提供数据驱动的高层 Tree、可完全自定义渲染的 TreeRoot / TreeItem,以及面向大数据量的 TreeVirtualizer。
import { Tree, TreeItem, TreeRoot, TreeVirtualizer } from '@skyroc/web-ui';何时使用
- 需要展示父子层级结构,如目录、菜单、分类、权限树。
- 需要在层级节点上进行单选或多选。
- 需要自定义节点内容,如图标、状态、徽标或操作区。
- 数据量较大且展开后节点很多时,使用
TreeVirtualizer。
基础用法
通过 items 传入树数据。每个节点至少需要 value 和 label,有子节点时使用 children。
<Tree items={items} defaultExpanded={['components']} defaultValue="button" />多选
设置 multiple 后,value 和 defaultValue 使用字符串数组。默认 selectionBehavior="toggle",点击已选节点会取消选择。
<Tree multiple items={items} value={value} onValueChange={nextValue => setValue(nextValue as string[])} />自定义渲染
通过 renderItem 自定义节点内容。回调会收到当前节点、展开状态、选中状态、半选状态以及树级操作方法。
<Tree
items={items}
renderItem={({ item, isExpanded, hasChildren }) => (
<>
{hasChildren ? <FolderIcon open={isExpanded} /> : <FileIcon />}
<span>{item.data.label}</span>
</>
)}
/>虚拟滚动
TreeVirtualizer 适合展开后节点数量较多的场景。需要设置 height,并通过 itemSize 提供预估行高。
<TreeVirtualizer height={300} itemSize={36} items={items} />选择传播
Tree 支持父子节点选择联动:
| 属性 | 说明 |
|---|---|
allowParentSelect | 允许选中有子节点的父节点 |
propagateSelect | 多选时选中父节点会向下联动选择子节点 |
bubbleSelect | 多选时子节点全选后向上联动选择父节点 |
selectionBehavior | toggle 可取消已选节点,replace 替换选择 |
<Tree multiple allowParentSelect propagateSelect bubbleSelect items={items} />展开行为
defaultExpanded 设置非受控初始展开项,expanded + onExpandedChange 用于受控展开。toggleBehavior="single" 会让同层路径保持单展开。
<Tree expanded={expanded} toggleBehavior="single" onExpandedChange={setExpanded} />API
Tree
高层数据驱动组件。继承 TreeRoot 的状态能力,并自动渲染 TreeItem。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| items* | 树节点数据 | TreeItemData[] | - |
| value | 受控选中值;单选为字符串,多选为字符串数组 | string | string[] | - |
| defaultValue | 非受控默认选中值 | string | string[] | - |
| onValueChange | 选中值变化时触发 | (value: string | string[]) => void | - |
| expanded | 受控展开节点值列表 | string[] | - |
| defaultExpanded | 非受控默认展开节点值列表 | string[] | [] |
| onExpandedChange | 展开值变化时触发 | (expanded: string[]) => void | - |
| multiple | 是否启用多选 | boolean | false |
| selectionBehavior | 选择行为;toggle 可取消已选节点,replace 替换当前选择 | 'replace' | 'toggle' | 'toggle' |
| toggleBehavior | 展开行为;single 保持单展开路径,multiple 允许多个节点展开 | 'multiple' | 'single' | 'multiple' |
| allowParentSelect | 是否允许选择有子节点的父节点 | boolean | false |
| propagateSelect | 多选时是否将父节点选择向下传播给子节点 | boolean | false |
| bubbleSelect | 多选时是否在子节点全选后向上选择父节点 | boolean | false |
| disabled | 是否禁用整棵树 | boolean | false |
| disabledSelect | 是否禁用节点选择 | boolean | false |
| disabledToggle | 是否禁用节点展开/收起 | boolean | false |
| indentSize | 每级缩进宽度,单位 px | number | 16 |
| renderItem | 自定义节点内容渲染函数 | (props: TreeItemRenderProps & { item: FlattenedItem } & TreeRootRenderProps) => ReactNode | - |
| className | 根节点自定义 class | ClassValue | - |
| classNames | 各 slot 的自定义 class(root / item / virtualContainer / virtualContent) | TreeClassNames | - |
| top | 显示在树顶部的内容 | ReactNode | - |
| bottom | 显示在树底部的内容 | ReactNode | - |
TreeRoot
底层根组件,负责状态、上下文和无序列表语义,节点渲染完全交给 children 函数。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| children* | 自定义渲染函数,接收扁平节点列表、选中值、展开值和操作方法 | (props: TreeRootRenderProps) => ReactNode | - |
| items* | 树节点数据 | TreeItemData[] | - |
| value | 受控选中值 | string | string[] | - |
| expanded | 受控展开节点值列表 | string[] | - |
| multiple | 是否启用多选 | boolean | false |
| className | 根节点自定义 class | ClassValue | - |
TreeItem
底层节点组件,必须放在 TreeRoot 或 TreeVirtualizer 上下文中使用。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| value* | 节点唯一值 | string | - |
| level* | 节点层级,从 1 开始 | number | - |
| children | 节点内容,或接收节点状态的渲染函数 | ReactNode | (props: TreeItemRenderProps) => ReactNode | - |
| disabled | 是否禁用当前节点 | boolean | - |
| disabledSelect | 是否禁用当前节点选择 | boolean | - |
| disabledToggle | 是否禁用当前节点展开/收起 | boolean | - |
| indentSize | 每级缩进宽度,单位 px | number | 16 |
| onSelect | 节点选择事件回调;可通过 preventDefault 阻止默认选择 | (event: TreeSelectEvent) => void | - |
| onToggle | 节点展开/收起事件回调;可通过 preventDefault 阻止默认切换 | (event: TreeToggleEvent) => void | - |
TreeVirtualizer
虚拟滚动树组件。继承 Tree 状态能力,并使用 @tanstack/react-virtual 只渲染可视区域节点。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| height* | 虚拟滚动容器高度 | number | string | - |
| items* | 树节点数据 | TreeItemData[] | - |
| itemSize | 预估节点高度,或根据索引返回高度的函数 | number | (index: number) => number | 36 |
| overscan | 额外渲染的节点数量 | number | 5 |
| dynamic | 是否使用动态节点高度测量模式 | boolean | false |
| width | 虚拟滚动容器宽度 | number | string | '100%' |
| onScroll | 滚动偏移变化时触发 | (offset: number) => void | - |
| virtualizerRef | 虚拟滚动实例引用 | TreeVirtualizerRef | - |
| classNames | 各 slot 的自定义 class,额外支持 virtualContainer / virtualContent | TreeVirtualizerClassNames | - |
类型
TreeItemBaseData
树节点的基础数据结构。
| 字段 | 类型 | 说明 |
|---|---|---|
| value | string | 节点唯一值。 |
| label | ReactNode | 节点展示内容。 |
| disabled | boolean | 是否禁用节点。 |
FlattenedItem
Tree 内部渲染使用的扁平节点结构。
| 字段 | 类型 | 说明 |
|---|---|---|
| _id | string | 内部唯一标识。 |
| value | string | 节点值。 |
| label | ReactNode | 节点标签。 |
| data | TreeItemData | 原始节点数据。 |
| level | number | 节点层级。 |
| index | number | 同级索引。 |
| parent | TreeItemData | 父节点数据。 |
| hasChildren | boolean | 是否有子节点。 |
TreeRootRenderProps
TreeRoot children 函数和 renderItem 可用的树级状态与操作。
| 字段 | 类型 | 说明 |
|---|---|---|
| expanded | string[] | 当前展开节点值列表。 |
| flattenItems | FlattenedItem[] | 当前可见的扁平节点列表。 |
| modelValue | string | string[] | undefined | 当前选中值。 |
| select | (value: string) => void | 选择节点。 |
| toggle | (value: string) => void | 展开或收起节点。 |
TreeItemRenderProps
TreeItem children 函数和 Tree renderItem 可用的节点状态。
| 字段 | 类型 | 说明 |
|---|---|---|
| hasChildren | boolean | 是否有子节点。 |
| isExpanded | boolean | 是否已展开。 |
| isSelected | boolean | 是否已选中。 |
| isIndeterminate | boolean | undefined | 是否处于半选状态。 |
TreeClassNames
Tree 各 slot 的自定义 class。
| 字段 | 类型 | 说明 |
|---|---|---|
| root | ClassValue | 根节点 class。 |
| item | ClassValue | 节点 class。 |
| itemIndicator | ClassValue | 节点指示器 class。 |
| itemChildren | ClassValue | 子节点容器 class。 |
| virtualContainer | ClassValue | 虚拟滚动容器 class。 |
| virtualContent | ClassValue | 虚拟滚动内容层 class。 |
TreeProps
Tree 高层组件属性。
| 字段 | 类型 | 说明 |
|---|---|---|
| items | TreeItemData[] | 树节点数据。 |
| value | string | string[] | 受控选中值。 |
| expanded | string[] | 受控展开值。 |
| multiple | boolean | 是否多选。 |
| renderItem | (props: TreeItemRenderProps & { item: FlattenedItem } & TreeRootRenderProps) => ReactNode | 自定义节点渲染函数。 |
| classNames | TreeClassNames | 各 slot 的自定义 class。 |
TreeRootProps
TreeRoot 底层根组件属性。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | (props: TreeRootRenderProps) => ReactNode | 自定义渲染函数。 |
| items | TreeItemData[] | 树节点数据。 |
| value | string | string[] | 受控选中值。 |
| expanded | string[] | 受控展开值。 |
| multiple | boolean | 是否多选。 |
| className | ClassValue | 根节点 class。 |
TreeItemProps
TreeItem 底层节点组件属性。
| 字段 | 类型 | 说明 |
|---|---|---|
| value | string | 节点唯一值。 |
| level | number | 节点层级。 |
| children | ReactNode | (props: TreeItemRenderProps) => ReactNode | 节点内容。 |
| disabled | boolean | 是否禁用节点。 |
| onSelect | (event: TreeSelectEvent) => void | 选择事件回调。 |
| onToggle | (event: TreeToggleEvent) => void | 展开/收起事件回调。 |
TreeVirtualizerProps
TreeVirtualizer 虚拟滚动树属性。
| 字段 | 类型 | 说明 |
|---|---|---|
| height | number | string | 容器高度。 |
| items | TreeItemData[] | 树节点数据。 |
| itemSize | number | (index: number) => number | 预估节点高度。 |
| overscan | number | 额外渲染节点数量。 |
| dynamic | boolean | 是否动态测量节点高度。 |
| virtualizerRef | TreeVirtualizerRef | 虚拟滚动引用。 |
| classNames | TreeVirtualizerClassNames | 各 slot 的自定义 class。 |
TreeVirtualizerClassNames
TreeVirtualizer 支持的 classNames 结构。
| 字段 | 类型 | 说明 |
|---|---|---|
| root | ClassValue | 虚拟内容 ul 的 class。 |
| item | ClassValue | 节点 class。 |
| virtualContainer | ClassValue | 滚动容器 class。 |
| virtualContent | ClassValue | 虚拟内容层 class。 |
TreeVirtualizerRef
TreeVirtualizer 暴露的命令式引用。
| 字段 | 类型 | 说明 |
|---|---|---|
| containerRef | div element | null | 滚动容器元素。 |
| flattenItems | FlattenedItem[] | 当前可见扁平节点。 |
| scrollToIndex | (index: number, options?) => void | 滚动到指定索引。 |
| scrollToValue | (value: string, options?) => void | 滚动到指定节点值。 |
| virtualizer | object | @tanstack/react-virtual 实例。 |
TreeSelectEvent
节点选择事件的 detail 字段。
| 字段 | 类型 | 说明 |
|---|---|---|
| value | string | 节点值。 |
| isExpanded | boolean | 事件发生前是否展开。 |
| isSelected | boolean | 事件发生前是否选中。 |
| originalEvent | native mouse or keyboard event | 原始事件。 |
TreeToggleEvent
节点展开/收起事件的 detail 字段。
| 字段 | 类型 | 说明 |
|---|---|---|
| value | string | 节点值。 |
| isExpanded | boolean | 事件发生前是否展开。 |
| isSelected | boolean | 事件发生前是否选中。 |
| originalEvent | native mouse or keyboard event | 原始事件。 |
TreeRootContextValue
Tree 内部上下文值,供底层 TreeItem 读取状态。
| 字段 | 类型 | 说明 |
|---|---|---|
| items | TreeItemData[] | 原始树数据。 |
| expanded | string[] | 展开值列表。 |
| selectedKeys | string[] | 选中值列表。 |
| expandedItems | FlattenedItem[] | 当前可见扁平节点。 |
| onSelect | (value: string) => void | 选择节点。 |
| onToggle | (value: string) => void | 展开或收起节点。 |
StyledComponentProps<T>
项目内用于包装组件 props 的通用类型。
| 字段 | 类型 | 说明 |
|---|---|---|
| ...sourceProps | inherited props without className | 继承原始组件属性,但重新定义 className。 |
| className | ClassValue | 组件 class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 项目统一尺寸类型。 |