news 2026/9/20 20:44:33

ant-design-vue TreeSelect 树选择组件完全指南:API 详解、源码实现与实战示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ant-design-vue TreeSelect 树选择组件完全指南:API 详解、源码实现与实战示例

ant-design-vue TreeSelect 树选择组件完全指南:API 详解、源码实现与实战示例

【免费下载链接】ant-design-vue🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue

TreeSelect 是 ant-design-vue 提供的树型选择控件,它复用 Select 的选择交互,但选项数据结构是树形的,天然适合公司层级、学科系统、分类目录等层级化数据的录入场景。本文以 components/tree-select/index.zh-CN.md 为骨架,结合组件源码 components/tree-select/index.tsx、官方 Demo(basic.vue 等 13 个示例)与单元测试,系统讲解 TreeSelect 的全部 API、常用场景组合与底层实现原理,帮助你从会用走向用得明白。

何时使用 TreeSelect

TreeSelect 与 Select 的交互方式类似(点击展开下拉、输入过滤、多选打 Tag),唯一区别在于选项的数据结构是树形的。当你的候选数据存在明显的层级关系时,例如:

  • 公司组织架构(部门 → 小组 → 成员);
  • 学科体系(学院 → 专业 → 课程);
  • 商品/内容分类目录(一级分类 → 二级分类 → 叶子节点)。

就应当优先选用 TreeSelect,它内置了父节点展开/收起、子树级联勾选、异步加载子节点等树形交互能力,而普通 Select 只能平铺展示所有选项。

快速上手:基本用法

先看官方最简示例 basic.vue,它演示了v-model:value受控取值、show-search搜索、allow-clear清除、tree-default-expand-all默认展开以及treeData数据源:

<template> <a-tree-select v-model:value="value" show-search style="width: 100%" :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="Please select" allow-clear tree-default-expand-all :tree-data="treeData" tree-node-filter-prop="label" > <template #title="{ value: val, label }"> <b v-if="val === 'parent 1-1'" style="color: #08c">sss</b> <template v-else>{{ label }}</template> </template> </a-tree-select> </template> <script lang="ts" setup> import { ref, watch } from 'vue'; import type { TreeSelectProps } from 'ant-design-vue'; const value = ref<string>(); const treeData = ref<TreeSelectProps['treeData']>([ { label: 'root 1', value: 'root 1', children: [ { label: 'parent 1', value: 'parent 1', children: [ { label: 'parent 1-0', value: 'parent 1-0', children: [ { label: 'my leaf', value: 'leaf1' }, { label: 'your leaf', value: 'leaf2' }, ]}, { label: 'parent 1-1', value: 'parent 1-1' }, ], }, { label: 'parent 2', value: 'parent 2' }, ], }, ]); watch(value, () => { console.log(value.value); }); </script>

要点说明:

  • v-model:value:组件的受控值。在源码 index.tsx 中声明了'onUpdate:value'事件,因此支持 Vue 3 的v-model:value语法;单选时是string,多选/可勾选时是string[]
  • #title插槽:自定义树节点渲染,插槽参数中包含valuelabeltitle等字段,可用作高亮、图标或富文本展示;
  • tree-node-filter-prop="label":指明搜索过滤时依据label字段匹配(默认是value)。

TreeSelect 完整 API 详解

TreeSelect 共提供 42 个核心属性,本文按数据、选择、搜索、展开加载、外观交互五个维度分组讲解,保证每个参数都给出类型、默认值与适用场景。

数据配置:treeData / treeDataSimpleMode / fieldNames

参数说明类型默认值版本
treeDatatreeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(value 在整个树范围内唯一)array<{value, label, children, [disabled, disableCheckbox, selectable]}>[]
treeDataSimpleMode使用简单格式的 treeData(此时 treeData 应为[{id:1, pId:0, value:'1', label:"test1",...}]pId是父节点的 id),可传入对象自定义id/pId字段名false | Array<{ id: string, pId: string, rootPId: null }>false
fieldNames替换 treeNode 中 label、value、children 字段为 treeData 中对应的字段object{children:'children', label:'title', value:'value'}3.0.0
replaceFields替换 treeNode 中 label、value、key、children 字段(旧 API)object{children:'children', label:'title', key:'key', value:'value'}1.6.1(3.0.0 废弃)
treeNodeLabelProp作为显示内容的 prop 设置string'title'
  • treeData 是首选数据源。源码 index.tsx 在初始化时会发出警告:children方式(手写a-tree-select-node)已废弃,请改用treeData
  • treeDataSimpleMode 扁平化数据:当后端返回的是id/pId扁平列表时,无需手动组装嵌套结构,组件会自动按pId建树。异步加载示例 async.vue 即采用此模式;
  • fieldNames 适配后端字段名:后端字段叫name而非title时,通过:field-names="{ children: 'children', label: 'name', value: 'value' }"映射,完整示例见 replaceFields.vue。对应地,tree-node-filter-prop也要同步改为"name"
  • replaceFields 已废弃:源码 index.tsx 会打印replaceFields is deprecated, please use fieldNames instead的告警,且实现上直接取fieldNames = props.replaceFields(index.tsx)兼容旧写法。

选择与回填:value / multiple / treeCheckable / showCheckedStrategy

参数说明类型默认值版本
value(v-model)指定当前选中的条目string/string[]-
defaultValue指定默认选中的条目(非受控)string/string[]-
multiple支持多选(设置 treeCheckable 时自动变为 true)booleanfalse
treeCheckable显示 checkboxbooleanfalse
treeCheckStrictlycheckable 状态下节点选择完全受控(父子节点选中状态不再关联),会使labelInValue强制为 truebooleanfalse
showCheckedStrategy定义选中项回填方式:TreeSelect.SHOW_ALL显示所有选中节点(含父节点);TreeSelect.SHOW_PARENT只显示父节点(其下所有子节点均选中时);默认只显示子节点enum{SHOW_ALL, SHOW_PARENT, SHOW_CHILD}TreeSelect.SHOW_CHILD
labelInValue是否把每个选项的 label 包装进 value,value 类型从string变为{value: string, label: VNode, halfChecked: string[]}booleanfalse
  • multipletreeCheckable的关系:源码 index.tsx 计算isMultiple = !!(props.treeCheckable || props.multiple),即开启treeCheckable时多选自动生效,同时会输出告警提示你无需再手动传multiple
  • showCheckedStrategy的用法:在 checkable.vue 中通过import { TreeSelect } from 'ant-design-vue'TreeSelect.SHOW_PARENT,用于"父节点全选中时只回填父节点"。这三个常量由源码 index.tsx 通过Object.assign(TreeSelect, { TreeNode, SHOW_ALL, SHOW_PARENT, SHOW_CHILD, install })静态挂载;
  • treeCheckStrictly:适合"父子独立勾选"的场景(如权限分配),此时labelInValue被强制置为 true;
  • 多选 Tag 的辅助参数maxTagCount(最多显示 tag 数)、maxTagPlaceholder(隐藏 tag 时的占位内容,slot/function(omittedValues)),在 virtual-scroll.vue 中可以看到:max-tag-count="10"的实际用法。

搜索与过滤:showSearch / filterTreeNode / searchValue

参数说明类型默认值版本
showSearch在下拉中显示搜索框(仅在单选模式下生效)booleanfalse
searchPlaceholder搜索框默认文字string|slot-
searchValue(v-model)搜索框的值,可通过search事件获取用户输入string-
filterTreeNode是否根据输入项进行筛选,默认用 treeNodeFilterProp 的值作为要筛选的属性;也可传Function(inputValue, treeNode)自定义(需返回 bool)boolean | FunctionFunction
treeNodeFilterProp输入项过滤对应的 treeNode 属性string'value'
  • 单选模式下开启show-search后,下拉面板顶部会出现搜索框,输入内容即时过滤树节点;多选模式本身就支持输入过滤,无需额外开启;
  • searchValuesearch事件配合可实现搜索值的完全受控:源码 index.tsx 中handleSearch同时触发update:searchValuesearch,即v-model:search-value可直接绑定;
  • 若树节点显示文本与 value 不一致(如 value 是编码、label 是名称),记得将treeNodeFilterProp设为'label',否则按默认的value过滤可能搜不到用户想输入的中文名。

展开与异步加载:treeExpandedKeys / loadData / treeLoadedKeys

参数说明类型默认值版本
treeDefaultExpandAll默认展开所有树节点booleanfalse
treeDefaultExpandedKeys默认展开的树节点(非受控)string[] | number[]-
treeExpandedKeys(v-model)设置展开的树节点(受控)string[] | number[]-
loadData异步加载数据function(node)-
treeLoadedKeys(受控)已经加载的节点,需要配合loadData使用string[][]3.3.0

异步加载的完整范式见 async.vue:配合tree-data-simple-mode使用扁平数据,onLoadData返回一个 Promise,在 Promise 中请求接口并追加子节点,resolve(true)通知组件展开完成:

const onLoadData = (treeNode: TreeSelectProps['treeData'][number]) => { return new Promise(resolve => { const { id } = treeNode.dataRef; setTimeout(() => { treeData.value = treeData.value.concat([ genTreeNode(id, false), genTreeNode(id, true), genTreeNode(id, true), ]); resolve(true); }, 300); }); };

注意loadData回调的treeNode对象需要通过treeNode.dataRef拿到原始数据(包含idisLeaf等字段),叶子节点应在数据中标记isLeaf: true,否则组件会一直尝试加载。

外观、尺寸与交互细节

参数说明类型默认值版本
allowClear显示清除按钮booleanfalse
disabled是否禁用booleanfalse
placeholder选择框默认文字string|slot-
size选择框大小,可选largesmallstring'default'
status设置校验状态'error' | 'warning'-3.3.0
placement选择框弹出的位置bottomLeftbottomRighttopLefttopRightbottomLeft3.3.0
suffixIcon自定义的选择框后缀图标VNode | slot-
treeIcon是否展示 TreeNode title 前的图标(无默认样式,需自行定义)booleanfalse
treeLine是否展示线条样式,可传{ showLeafIcon }对象控制叶子图标boolean | objectfalse3.0
virtual设置 false 时关闭虚拟滚动booleantrue3.0
listHeight设置弹窗滚动高度number256
dropdownMatchSelectWidth下拉菜单与选择器同宽,默认设置min-width,值小于选择框宽度时忽略;false 会关闭虚拟滚动boolean | numbertrue
dropdownStyle下拉菜单的样式object-
popupClassName下拉菜单的 classNamestring-4.0
getPopupContainer菜单渲染父节点,默认渲染到 body;遇到菜单滚动定位问题时可改为滚动区域并相对定位Function(triggerNode)() => document.body
notFoundContent下拉列表为空时显示的内容slotNot Found
tagRender自定义 tag 内容,多选时生效slot-3.0
title自定义标题slot-3.0.0

分组场景示例:

  • 校验状态status="error"/status="warning"可直接展示红/黄边框,见 status.vue。源码 index.tsx 通过getMergedStatus将 Form 表单上下文的校验状态与组件自身status合并,因此放进a-form-item时会自动继承表单校验结果,无需重复设置;
  • 弹出方向placement支持四个方向,默认bottomLeft;注意源码 index.tsx 中当 ConfigProvider 配置了 RTL 方向时,默认值会自动切换为bottomRight
  • 虚拟滚动virtual默认开启,配合listHeight(默认 256,见 index.tsx 的initDefaultProps)与listItemHeight(默认 26)渲染。当树节点数量很大(数千级)时建议保持开启,参考 virtual-scroll.vue 中递归生成 10×10×10 级别数据量级的示例;
  • 线条样式treeLine传布尔值开启连接线,传对象可控制showLeafIcon,见 tree-line.vue;其样式语义与 Tree 组件的 showLine 一致;
  • 自定义 Tag:多选模式下用#tagRender插槽接管已选项标签渲染,插槽参数为{ label, closable, onClose, option },custom-tag-render.vue 展示了利用option.color给不同节点 Tag 上色的做法;单选场景直接使用#title插槽即可;
  • 弹出容器getPopupContainer默认挂载到 body,若在滚动容器内出现下拉定位异常,应将其指向滚动区域并配合相对定位。

事件(Events)

事件名称说明回调参数版本
change选中树节点或输入值发生变化时调用function(value, label, extra)
dropdownVisibleChange展开/收起下拉菜单的回调function(open)3.0
search文本框值变化时回调function(value: string)
select树节点被选中时调用function(value, node, extra)
treeExpand展开树节点时调用function(expandedKeys)

源码 index.tsx 展示了事件转发链:handleChange先触发update:value(支撑 v-model),再触发change,最后通知FormItemContext.onFieldChange()让 Form 感知字段变化;handleSearch同理同时触发update:searchValuesearchhandleTreeExpand同时触发update:treeExpandedKeystreeExpand。这解释了为什么searchValuetreeExpandedKeys都能直接使用v-model语法。

Tree 方法(Methods)

名称描述
blur()移除焦点
focus()获取焦点

通过模板 ref 或useTemplateRef获取组件实例后调用。源码 index.tsx 用expose({ focus, blur })显式暴露这两个方法,内部委托给底层vc-tree-select的实例(treeSelectRef.value.focus?.())。

TreeNode props(组件式节点)

官方建议使用treeData代替手写 TreeNode,免去手工构造的麻烦。

参数说明类型默认值版本
checkable当树为 checkable 时,设置独立节点是否展示 Checkboxboolean-
disableCheckbox禁掉 checkboxbooleanfalse
disabled是否禁用booleanfalse
isLeaf是否是叶子节点booleanfalse
key此项必须设置(其值在整个树范围内唯一)string | number-
selectable是否可选booleantrue
title树节点显示的内容string|slot'---'
value默认根据此属性值进行筛选(其值在整个树范围内唯一)string-

这些字段同时对应treeData数组中单个节点的可选扩展属性:disableddisableCheckboxselectableisLeaf,在 checkable.vue 中可见{ label: 'Child Node3', value: '0-1-0', disabled: true }的用法——树数据中直接给节点打标即可,无需手动渲染组件节点。

源码实现:TreeSelect 是如何工作的

TreeSelect 在架构上是一层"薄封装",核心逻辑全部下沉到内部组件库 components/vc-tree-select(提供VcTreeSelectTreeNode以及SHOW_ALL/SHOW_PARENT/SHOW_CHILD常量),ant-design-vue 层负责:

  1. Props 归一化:在 treeSelectProps() 中从vcTreeSelectProps剔除showTreeIcontreeMotioninputIcon等内部细节,再补充suffixIconsizeborderedtreeLinestatuspopupClassName等对外属性,并通过initDefaultProps设置listHeight: 256treeIcon: falselistItemHeight: 26bordered: true等默认值;
  2. 废弃 API 告警:对children节点、treeCheckable时多余的multiplereplaceFieldsdropdownClassName分别输出 dev 警告(index.tsx);
  3. 主题与上下文集成:通过useConfigInject('select', props)继承 ConfigProvider 的prefixClssizegetPopupContainerdisableddropdownMatchSelectWidthvirtual等全局配置;结合FormItemInputContext实现表单校验联动;通过useCompactItemContext支持与a-space紧凑排列组合;
  4. 样式体系:样式基于 CSS-in-JS 实现——useSelectStyle(复用 Select 的样式)与useStyle(TreeSelect 专属样式)两个 wrapper 包裹渲染结果,wrapSelectSSR/wrapTreeSelectSSR同时支持 SSR 样式抽取;
  5. 插槽映射:将 Vue 插槽统一转换为v-slotscustomSlots传给底层组件,并注入默认的treeCheckable勾选框样式插槽(index.tsx)。

组件的单元测试位于 components/tree-select/tests/index.test.js,通过项目共享的focusTest(验证 focus/blur 方法)与mountTest(验证组件可正常挂载、卸载且无副作用)保证基础契约稳定;快照测试见 components/tree-select/tests/snapshots/demo.test.js.snap。

实践建议汇总

  • 数据量大(上千节点)时:保持virtual开启,必要时调小listHeight或通过dropdownMatchSelectWidth={false}释放滚动条空间;
  • 后端扁平接口:优先用tree-data-simple-mode+id/pId,避免前端递归组树;
  • 接口字段与组件默认字段不一致:用fieldNames映射,并同步调整tree-node-filter-prop
  • 表单校验:无需手动传status,放入a-form-item后校验状态会自动联动;需要手动展示时再传status="error" | "warning"
  • 多级勾选回填:按业务语义选择SHOW_ALL(完整展示)或SHOW_PARENT(聚合展示),默认SHOW_CHILD只回填叶子;
  • 异步加载:叶子节点务必标记isLeaf: true,并在loadData的 Promise resolve 后追加子节点数据。

如需查看更多场景,可直接阅读 components/tree-select/demo 目录下的全部 13 个示例(含 placement.vue、suffix.vue、highlight.vue),每个示例都是可直接复制运行的 Vue 3 SFC。

【免费下载链接】ant-design-vue🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 20:43:52

Swagger UI 在线验证指南:3 步看懂徽章、Schema 校验与错误标记

Swagger UI 在线验证指南&#xff1a;3 步看懂徽章、Schema 校验与错误标记 【免费下载链接】swagger-ui Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API. 项目地址: htt…

作者头像 李华
网站建设 2026/9/20 20:42:39

基于Qt和OpenGL从零构建带刻度标签的三维坐标系

简介&#xff1a;在OpenGL三维可视化开发中&#xff0c;带刻度标签的坐标系能更直观定位图形位置&#xff0c;而OpenGL本身不支持文字渲染&#xff0c;常需借助Qt的QOpenGLWidget解决。该资源面向具备一定Qt与OpenGL基础的中高级开发者&#xff0c;提供一套完整的三维坐标系绘制…

作者头像 李华
网站建设 2026/9/20 20:42:34

最大似然法遥感影像分类:原理、实操流程与常见问题

简介&#xff1a;面向遥感影像监督分类与精度评价的MATLAB实践资源&#xff0c;围绕8波段遥感影像的最大似然法分类任务展开。影像涵盖建筑物、道路、植被、水四类典型地物&#xff0c;训练样本与待分类像素按类别整理为独立表格&#xff0c;程序调用最大似然法完成像素归类&am…

作者头像 李华
网站建设 2026/9/20 20:39:28

基于YOLOv5s改进的铁路信号灯小目标检测与部署实践

简介&#xff1a;面向铁路安全运输场景&#xff0c;这套深度学习实践资料围绕卷积神经网络&#xff08;CNN&#xff09;的铁路信号灯识别方法展开&#xff0c;适合图像识别入门者、计算机视觉方向学生及铁路智能监测相关研究人员。资源以普通铁路信号灯为研究对象&#xff0c;从…

作者头像 李华
网站建设 2026/9/20 20:36:15

Podman system connection remove 详解:删除远程连接与清理实践

Podman system connection remove 详解&#xff1a;删除远程连接与清理实践 【免费下载链接】podman Podman: A tool for managing OCI containers and pods. 项目地址: https://gitcode.com/gh_mirrors/po/podman 摘要 本文围绕 docs/source/markdown/podman-system-c…

作者头像 李华