- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
TreeSelect(树形选择)是 TDesign 面向 UniApp 生态提供的一棵多层级树形选择组件,适用于省市区联动、商品分类、组织架构等"逐级下钻选择"场景。本文以 packages/uniapp-components/tree-select/README.en-US.md 为核心骨架,结合组件源码与官方示例,系统讲解其全部 Props、事件、外部样式类与 CSS 变量,并深入剖析其"侧边栏 + 树形列"的联动实现原理。
组件简介与引入方式
TreeSelect 通过t-side-bar、t-scroll-view、t-radio-group/t-checkbox-group等基础组件组合而成,核心用途是"适用于选择树形的数据结构"(见 README.md 前言)。
推荐使用 easycom 模式引入组件,配置后无需手动import即可直接在模板中使用<t-tree-select />。如需手动引入:
import TTreeSelect from '@tdesign/uniapp/tree-select/tree-select.vue';注意:根据 演示页说明,当前组件渲染框架支持情况为 WebView。
Props 属性详解
组件全部属性定义在 props.ts 中,类型声明见 type.ts。下表汇总了全部属性:
| 名称 | 类型 | 默认值 | 说明 | | -- | -- | -- | -- | | custom-style | Object | - | 自定义样式(CSS) | | custom-value | String / Number / Array | - | 自定义选中值,优先级高于value。TS 类型:TreeSelectValue| | height | String / Number | 336 | 高度,默认单位为 px | | keys | Object | - |value / label / disabled / children在options中的字段别名,如{ value: 'key', label: 'name', children: 'list' }。TS 类型:TreeKeysType,定义见 common/common.ts | | multiple | Boolean | false | 是否允许多选 | | options | Array | [] | 选项数据。TS 类型:Array<DataOption>| | value | String / Number / Array | - | 选中值,支持v-model:value语法糖。TS 类型:TreeSelectValue| | default-value | String / Number / Array | - | 选中值,非受控属性。TS 类型:TreeSelectValue|
核心类型TreeSelectValue与TreeLevel
export type TreeSelectValue = string | number | Array<TreeSelectValue>; export type TreeLevel = 0 | 1 | 2;TreeSelectValue是递归类型:既可以是单个string / number,也可以是元素为TreeSelectValue的数组——单选中每层取一个值(形如['5', '5-5']),多选中叶子层为数组(形如['5', ['5-0', '5-1']])。
数据字段映射keys
组件默认要求options节点使用value / label / disabled / children字段名。若接口返回的是其他字段名,可用keys重命名映射,其类型定义在 common/common.ts:
export interface KeysType { value?: string; label?: string; disabled?: string; } export interface TreeKeysType extends KeysType { children?: string; }示例:后端返回{ key, name, list }结构时,可传入keys="{ value: 'key', label: 'name', children: 'list' }"。从 tree-select.vue 源码 可见,buildTreeOptions正是用item[keys?.label || 'label']等表达式读取字段。
事件 Events
| 名称 | 参数 | 说明 | | -- | -- | -- | | change |(context: { value: TreeSelectValue, level: TreeLevel })| 点击任何节点均会触发;level代表当前点击的层级,0 代表最左侧,依次递进。type TreeLevel = 0 \| 1 \| 2|
从 tree-select.vue 源码 可以看到change事件的三种触发路径:
onRootChange(左侧 SideBar 切换):this._trigger('change', { value: innerValue, level: 0 })handleTreeClick(中间列点击):this._trigger('change', { value: innerValue, level: 1 })handleChange(右侧单选/多选):this._trigger('change', { value: innerValue, level })
此外,value被声明为controlledProps(见 instantiationDecorator.js),_trigger会额外$emit('update:value', detail.value),这正是v-model:value语法糖的实现基础。
外部样式类 External Classes
组件通过externalClasses暴露以下样式注入点(声明见 tree-select.vue 源码):
| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 | | t-class-left-column | 左侧第一列样式类 | | t-class-left-item | 左侧第一列子项样式类 | | t-class-middle-item | 中间列子项样式类 | | t-class-right-column | 右侧第一列样式类 | | t-class-right-item | 右侧第一列子项样式类 | | t-class-right-item-label | 右侧第一列子项标签样式类 |
CSS 变量
组件在 tree-select.less 中为每项样式声明了var(--td-xxx, 默认值)兜底,因此可通过覆盖下列 CSS 变量实现全局或局部定制:
| 变量名 | 默认值 | 说明 | | -- | -- | -- | | --td-tree-bg-color | @bg-color-container | 组件背景色 | | --td-tree-colum-text-color | @text-color-primary | 列文字颜色 | | --td-tree-colum-width | 206rpx | 列宽度 | | --td-tree-item-active-color | @brand-color | 选中项文字颜色 | | --td-tree-item-disabled-color | @text-color-disabled | 禁用项颜色 | | --td-tree-item-font-size | 32rpx | 选项字号 | | --td-tree-item-height | 112rpx | 选项高度 | | --td-tree-root-bg-color | @bg-color-secondarycontainer | 左侧根列背景色 |
这些 Less 变量(如@bg-color-container、@brand-color等)定义于 common/style/_variables.less,默认值本身也是var(--td-...),支持 TDesign 的全局主题变量体系覆盖。
从 less 源码还可看到对应样式规则:.t-tree-select__column--left使用根背景色、--right使用flex: 1撑满剩余宽度;__item--active加粗并着色,__item--disabled通过pointer-events: none禁用交互。
实战示例
基础单选:两级树形
官方 base 示例 展示了最基本的用法:
<template> <view> <t-tree-select :options="options" :value="value" @change="onChange" /> </view> </template> <script> import TTreeSelect from '@tdesign/uniapp/tree-select/tree-select.vue'; export default { components: { TTreeSelect }, data() { return { options: [ { label: '选项一', value: '0', children: [{ label: '选项一子项0', value: '0-0' }, ...] }, // ... ], value: ['5', '5-5'], }; }, methods: { onChange(e) { console.log('change: ', e); this.value = e.value; }, }, }; </script>多选:叶子层可勾选多项
multiple 示例 仅多传入multiple属性,右侧列即从t-radio-group切换为t-checkbox-group:
<t-tree-select :options="options" :value="value" multiple @change="onChange" />多选时value的叶子层为数组,如value: ['5', ['5-0', '5-1']]。
三级联动:省市区选择
normal 示例 用省市区数据构建三层树:
const options = [ { label: '北京市', value: '110000', children: [ { label: '北京市', value: '110100', children: [{ label: '东城区', value: '110101' }, ...] }, ], }, // 广东省 → 广州市/深圳市/... → 各区县 ]; // value: ['110000', '110100', '110101']三层结构完全由options的children嵌套层级决定,组件自动识别最大深度并按层渲染。
源码原理:从 options 到多列渲染
1. 树形数据扁平化(buildTreeOptions)
tree-select.vue 的 buildTreeOptions 是核心:从根节点开始,依据当前层选中值currentValue逐层定位currentNode(找不到则回退到该层第一个选项),直到没有children;随后调用getTreeDepth计算树的真实深度并补齐空层,得到每层选项列表treeOptions,最后一层记为leafLevel。
getTreeDepth定义在 common/utils.js,递归计算嵌套最大深度。
2. 三列布局定位
computed.js 的getTreeClass(level, total)根据当前层与总层数返回列样式方向:
export const getTreeClass = function (level, total) { if (level === 0) return 'right'; // 最左侧 → 右对齐内容 if (level === 1 && level !== total - 1) return 'middle'; return 'left'; };再结合 tree-select.vue 的getScrollViewClass:只有最后一列(最右侧)标记__column--right并用flex: 1撑满剩余宽度,其余列按--td-tree-colum-width固定宽度。
3. 层级联动与滚动定位
- 左侧第一层固定使用
t-side-bar/t-side-bar-item渲染;中间层渲染普通view;最右侧叶子层根据multiple渲染t-radio-group或t-checkbox-group。 - 每次层级变化会调用
getScrollIntoView,通过t-id="scroll-to-<value>"配合scroll-into-view让对应选项自动滚入可视区。 value / options / keys均被深度 watch(见 tree-select.vue),数据变化会立即重建树形结构。
常见问题与建议
- 为何设置了 value 但默认仍选中第一项?源码中
innerValue每层默认值回退为该层第一个选项(levelOptions[0]?.value),所以未显式传值时首项天然选中;多选模式下叶子层默认选中数组首项。 - 选中项位移导致的滚动问题:
scrollIntoView仅在初始化时计算,若后续通过外部数据驱动选中值变化,可考虑配合custom-value直接指定完整选中路径。 - 自定义字段名:优先使用
keys做字段映射,而不是改写数据,避免破坏受控value与事件的联动。
小结
TreeSelect 的完整能力集中体现在 README.en-US.md 与 type.ts 中:8 个 Props、1 个change事件、7 个外部样式类与 8 个 CSS 变量。结合 tree-select.vue 的实现可以看出,组件用"数据驱动的多层滚动列"替代传统下拉弹层,天然适合省市区、分类、组织架构等逐级选择场景;理解buildTreeOptions的扁平化与level语义,即可在业务中自由定制多级联动与多选逻辑。
- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
相关推荐
Ant Design Blazor TreeSelect 树形选择组件完整实战指南
Ant Design Blazor TreeSelect 树形选择组件完整实战指南 TreeSelect 是 Ant Design Blazor 中面向树形层级
UI组件前端Vue3-Treeselect树形选择器完整使用指南
Vue3 Treeselect树形选择器完整使用指南 在现代Web应用开发中,处理层级数据结构的需求日益增多。Vue3 Treeselect作为专为Vue 3设
数字人口播视频本地生成:Duix.Avatar 离线部署与首个视频产出指南
数字人口播视频本地生成:Duix.Avatar 离线部署与首个视频产出指南 Duix.Avatar 是一套完全离线运行的开源数字人工具:上传一段带人声的说话视频
人工智能AI 应用数字人媒体生成桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考