JGuang

树形控件

Tree · Ant Design

交互预览
npm install antd@6.6.5 @ant-design/icons@6.3.4 dayjs@1.11.23

树形控件

多层次的结构列表。

何时使用

文件夹、组织架构、生物分类、国家地区等等,世间万物的大多数结构都是树形结构。使用 树控件 可以完整展现其中的层级关系,并具有展开收起选择等交互功能。

代码演示

  • 基本 · basic

  • 受控操作示例 · basic-controlled

  • 拖动示例 · draggable

  • 异步数据加载 · dynamic

  • 可搜索 · search

  • 连接线 · line

  • 自定义图标 · customized-icon

  • 目录 · directory

  • 自定义展开/折叠图标 · switcher-icon

  • 虚拟滚动 · virtual-scroll

  • 滚动到嵌套节点 · scroll-to

  • 占据整行 · block-node

  • 自定义语义结构的样式和类 · style-class

API

通用属性参考:通用属性

Tree props

参数说明类型默认值版本全局配置
allowDrop是否允许拖拽时放置在该节点({ dropNode, dropPosition }) => boolean-×
autoExpandParent是否自动展开父节点booleanfalse×
blockNode是否节点占据一行booleanfalse×
checkable节点前添加 Checkbox 复选框booleanfalse×
checkedKeys(受控)选中复选框的树节点(注意:父子节点有关联,如果传入父节点 key,则子节点自动选中;相应当子节点 key 都传入,父节点也自动选中。当设置 checkable 和 checkStrictly,它是一个有checked和halfChecked属性的对象,并且父子节点的选中与否不再关联string[] | {checked: string[], halfChecked: string[]}[]×
checkStrictlycheckable 状态下节点选择完全受控(父子节点选中状态不再关联)booleanfalse×
classNames用于自定义组件内部各语义化结构的 class,支持对象或函数Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string>-6.0.0
defaultCheckedKeys默认选中复选框的树节点string[][]×
defaultExpandAll默认展开所有树节点booleanfalse×
defaultExpandedKeys默认展开指定的树节点string[][]×
defaultExpandParent默认展开父节点booleantrue×
defaultSelectedKeys默认选中的树节点string[][]×
disabled将树禁用booleanfalse×
draggable设置节点可拖拽,可以通过 icon: false 关闭拖拽提示图标boolean | ((node: DataNode) => boolean) | { icon?: React.ReactNode | false, nodeDraggable?: (node: DataNode) => boolean }falseconfig: 4.17.0×
expandedKeys(受控)展开指定的树节点string[][]×
fieldNames自定义节点 title、key、children 的字段object{ title: title, key: key, children: children }4.17.0×
filterTreeNode按需筛选树节点(高亮),返回 truefunction(node)-×
height设置虚拟滚动容器高度,设置后内部节点不再支持横向滚动number-×
icon在标题之前插入自定义图标。需要设置 showIcon 为 trueReactNode | (props) => ReactNode-×
loadData异步加载数据function(node)-×
loadedKeys(受控)已经加载的节点,需要配合 loadData 使用string[][]×
motion自定义树的动画配置CSSMotionProps-×
multiple支持点选多个节点(节点本身)booleanfalse×
rootStyleTree 最外层样式,请使用 styles.root 替代CSSProperties-4.20.0×
selectable是否可选中booleantrue×
selectedKeys(受控)设置选中的树节点,多选需设置 multiple 为 truestring[]-×
showIcon控制是否展示 icon 节点,没有默认样式booleanfalse×
showLine是否展示连接线boolean | { showLeafIcon: ReactNode | ((props: AntTreeNodeProps) => ReactNode) }false×
styles用于自定义组件内部各语义化结构的行内 style,支持对象或函数Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties>-6.0.0
switcherIcon自定义树节点的展开/折叠图标(showLine 下不会自动 rotate)ReactNode | ((props: AntTreeNodeProps) => ReactNode)-renderProps: 4.20.0×
switcherLoadingIcon自定义树节点的加载图标ReactNode-5.20.0×
titleRender自定义渲染节点(nodeData) => ReactNode-4.5.0×
treeDatatreeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一)array<{key, title, children, [disabled, selectable]}>-×
virtual设置 false 时关闭虚拟滚动booleantrue4.1.0×
onCheck点击复选框触发function(checkedKeys, e:{checked: boolean, checkedNodes, node, event, halfCheckedKeys})-×
onDoubleClick双击树节点触发function(event, node)-×
onDragEnddragend 触发时调用function({event, node})-×
onDragEnterdragenter 触发时调用function({event, node, expandedKeys})-×
onDragLeavedragleave 触发时调用function({event, node})-×
onDragOverdragover 触发时调用function({event, node})-×
onDragStart开始拖拽时调用function({event, node})-×
onDropdrop 触发时调用function({event, node, dragNode, dragNodesKeys})-×
onExpand展开/收起节点时触发function(expandedKeys, {expanded: boolean, node})-×
onLoad节点加载完毕时触发function(loadedKeys, {event, node})-×
onRightClick响应右键点击function({event, node})-×
onSelect点击树节点触发function(selectedKeys, e:{selected: boolean, selectedNodes, node, event})-×

TreeNode props

参数说明类型默认值
checkable当树为 checkable 时,设置独立节点是否展示 Checkboxboolean-
disableCheckbox禁掉 checkboxbooleanfalse
disabled禁掉响应booleanfalse
icon自定义图标。可接收组件,props 为当前节点 propsReactNode | (props) => ReactNode-
isLeaf设置为叶子节点 (设置了 loadData 时有效)。为 false 时会强制将其作为父节点boolean-
key被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复!string(内部计算出的节点位置)
selectable设置节点是否可被选中booleantrue
title标题ReactNode---

DirectoryTree props

参数说明类型默认值
expandAction目录展开逻辑,可选:false | click | doubleClickstring | booleanclick

注意

在 3.4.0 之前:树节点可以有很多,但在设置 checkable 时,将会花费更多的计算时间,因此我们缓存了一些计算结果(this.treeNodesStates)来复用,避免多次重复计算,以此提高性能。但这也带来了一些限制,当你异步加载树节点时,你需要这样渲染树:

{
  this.state.treeData.length ? (
    <Tree>
      {this.state.treeData.map((data) => (
        <TreeNode />
      ))}
    </Tree>
  ) : (
    'loading tree'
  );
}

Tree 方法

名称说明
scrollTo({ key: string | number; align?: 'top' | 'bottom' | 'auto'; offset?: number; autoExpand?: boolean })虚拟滚动下,滚动到指定 key 条目。非受控模式下可通过 autoExpand 展开目标节点

Tree Hooks

Tree.useTree

type Tree.useTree = (treeData: DataNode[], config: { fieldNames?: FieldNames }) => TreeInstance

提供 Tree 数据工具。getPath(key) 返回从根节点到目标节点的实体路径,可用于在受控模式下更新 expandedKeys。

getPath 的函数引用保持稳定,并在调用时读取最新的 treeData。如果对 getPath 的派生结果进行 memo,请将 treeData 和查询 key 加入依赖项,因为依赖追踪无法感知 getPath 内部捕获的数据。

const { getPath } = Tree.useTree(treeData, {});

const path = useMemo(() => getPath(selectedKey), [getPath, selectedKey, treeData]);

Semantic DOM

语义节点原生说明版本
root根元素,设置树形控件的基础样式、布局和容器控制6.0.0
item条目元素,设置树节点的基础样式、拖拽状态、角色属性、缩进、切换器、内容包装器等节点结构6.0.0
itemIcon图标元素,设置树节点图标的样式、尺寸和状态显示6.0.0
itemTitle标题元素,设置树节点标题文字的显示样式和文本内容6.0.0
itemSwitcher展开收起切换器元素,设置树节点展开/收起按钮的样式和背景6.4.0

语义说明来源: vendor/components/tree/demo/_semantic.tsx

主题变量(Design Token)

类型、继承关系和原生令牌声明保持固定源码原文;默认值由原生主题计算,并可能受 ConfigProvider 覆盖。本表不伪造静态默认值。

令牌类型原生说明
directoryNodeSelectedColorstring目录树节点选中文字颜色
directoryNodeSelectedBgstring目录树节点选中背景色

声明来源: vendor/components/tree/style/index.ts

import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';

import { Keyframes, unit } from '@ant-design/cssinjs';

import { getStyle as getCheckboxStyle } from '../../checkbox/style';

import { genFocusOutline, resetComponent } from '../../style';

import { genCollapseMotion } from '../../style/motion';

import type { AliasToken, CSSUtil, FullToken, GetDefaultToken } from '../../theme/internal';

import { genStyleHooks, mergeToken } from '../../theme/internal';

import { genDirectoryStyle } from './directory';

export interface TreeSharedToken {
  /**
   * @desc 节点标题高度
   * @descEN Node title height
   */
  titleHeight: number;
  /**
   * @desc 展开按钮宽度
   * @descEN Switcher width of tree
   */
  switcherSize?: number;
  /**
   * @desc 缩进宽度
   * @descEN Indent width of tree
   */
  indentSize?: number;
  /**
   * @desc 节点悬浮态背景色
   * @descEN Background color of hovered node
   */
  nodeHoverBg: string;
  /**
   * @desc 节点悬浮态态文字颜色
   * @descEN Text color of hovered node
   */
  nodeHoverColor: string;
  /**
   * @desc 节点选中态背景色
   * @descEN Background color of selected node
   */
  nodeSelectedBg: string;
  /**
   * @desc 节点选中态文字颜色
   * @descEN Text color of selected node
   */
  nodeSelectedColor: string;
}

export interface ComponentToken extends TreeSharedToken {
  /**
   * @desc 目录树节点选中文字颜色
   * @descEN Text color of selected directory node
   */
  directoryNodeSelectedColor: string;
  /**
   * @desc 目录树节点选中背景色
   * @descEN Background color of selected directory node
   */
  directoryNodeSelectedBg: string;
}

// =============================== Base ===============================
export type TreeToken = FullToken<'Tree'> & {
  treeCls: string;
  treeNodeCls: string;
  treeNodePadding: number | string;
};

FAQ

defaultExpandAll 在异步加载数据时为何不生效?

default 前缀属性只有在初始化时生效,因而异步加载数据时 defaultExpandAll 已经执行完成。你可以通过受控 expandedKeys 或者在数据加载完成后渲染 Tree 来实现全部展开。

虚拟滚动的限制

虚拟滚动通过在仅渲染可视区域的元素来提升渲染性能。但是同时由于不会渲染所有节点,所以无法自动拓转横向宽度(比如超长 title 的横向滚动条)。

disabled 节点在树中的关系是什么?

Tree 通过传导方式进行数据变更。无论是展开还是勾选,它都会从变更的节点开始向上、向下传导变化,直到遍历的当前节点是 disabled 时停止。因而如果控制的节点本身为 disabled 时,那么它只会修改本身而不会影响其他节点。举例来说,一个父节点包含 3 个子节点,其中一个为 disabled 状态。那么勾选父节点,只会影响其余两个子节点变成勾选状态。勾选两个子节点后,无论 disabled 节点什么状态,父节点都会变成勾选状态。

这种传导终止的方式是为了防止通过勾选子节点使得 disabled 父节点变成勾选状态,而用户无法直接勾选 disabled 父节点更改其状态导致的交互矛盾。如果你有着自己的传导需求,可以通过 checkStrictly 自定义勾选逻辑。

原生通用属性

Tips: 以下通用属性适用于 antd 大部分组件,不支持的组件会单独说明。

参数说明类型默认值
style自定义样式CSSProperties-
className自定义类名string-
rootClassName添加在组件最外层的 classNamestring-
autoFocus自动获取焦点,仅对表单类、链接、交互容器等可聚焦元素生效booleanfalse

安装并复现示例

npm install antd@6.6.5 @ant-design/icons@6.3.4 dayjs@1.11.23

使用 ConfigProvider 和原生 App,并单独配置 dayjs 语言。每个示例在查看代码中列出完整源码文件和额外固定依赖。示例名称用于选择演示,不是组件通用属性。主题、语言与 SSR 初始化见资源安装指南。

原生类型参考

源码查看器包含未修改的原生实现和以下声明文件,继承类型仍位于原生包中。代码中的英文注释保留为源码参考。

  • vendor/components/tree/DirectoryTree.tsx
  • vendor/components/tree/Tree.tsx
  • vendor/components/tree/index.tsx
  • vendor/components/tree/style/index.ts
  • vendor/components/tree/utils/dictUtil.ts
  • vendor/components/tree/utils/dropIndicator.tsx
  • vendor/components/tree/utils/iconUtil.tsx

来源与许可

https://github.com/ant-design/ant-design/tree/4a39f54842eade4e565ab336ef6097cd7e723cdd

保留原生中英文正文与可执行示例;官网专用的嵌入章节和令牌表格在本地展开。Ant Design 使用 MIT 许可,另列依赖的许可证也需保留。上传预览禁止向外发起请求,不提供后端服务。