---
title: "TreeSelect 树选择器"
description: "在下拉浮层中选择树形数据的选择器"
category: Form
status: beta
since: 0.3.4
tags: [tree-select, form, hierarchy]
syncStatus: reviewed
verified: true
---

## 用法

### 基础
:::TuffDemoWrapper{demo="TreeSelectTreeSelectDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import type { TreeSelectNode, TreeSelectValue } from '@talex-touch/tuffex'
  import { ref } from 'vue'

  const multiple = ref(false)
  const value = ref<TreeSelectValue>(undefined)

  const nodes: TreeSelectNode[] = [
    {
      key: 'general',
      label: 'General',
      children: [
        { key: 'appearance', label: 'Appearance' },
        { key: 'language', label: 'Language' },
      ],
    },
    {
      key: 'danger',
      label: 'Danger Zone',
      disabled: true,
      children: [{ key: 'delete', label: 'Delete account', disabled: true }],
    },
  ]
  </script>

  <template>
    <TxTreeSelect v-model="value" :nodes="nodes" :multiple="multiple" :dropdown-max-height="260" />
  </template>
---
:::

### 权限编排
`TxTreeSelect` 选择归属团队，与 `TxTransfer`、`TxTimeline` 组成授权流程。
:::TuffDemoWrapper{demo="ComponentsPermissionOrchestrationDemo" code-lang="vue"}
---
code: |
  <template>
    <TxTreeSelect
      v-model="ownerTeam"
      :nodes="nodes"
      placeholder="归属团队"
      :default-expanded-keys="['ops']"
      :dropdown-max-height="220"
    />
  </template>
---
:::

### 最佳实践

- 紧凑的归属、命名空间、分类与组织单元选择用 `TxTreeSelect`；需要常驻上下文、批量操作或自定义行控件时用 `TxTree`。
- `nodes` 用稳定的 `key` 与 `label`，不要沿用旧选择器的 `value` 字段；`key` 不依赖本地化文案。
- 渲染前让值的形态匹配 `multiple`；运行时切换不会在标量与数组间自动转换。
- 默认展开保持浅层，例如根部门或产品域。
- `node` 插槽只放徽标或副标题，不要加与行选择竞争的点击目标。

## API 参考

### 属性

| 属性名 | 类型 | 默认值 | 说明 |
|------|------|---------|------|
| `modelValue` | `string \| number \| Array<string \| number> \| undefined` | - | 单选时为选中 key；`multiple` 时为 key 数组。 |
| `nodes` | `TreeSelectNode[]` | `[]` | 下拉树节点，也用于解析触发器文本。 |
| `multiple` | `boolean` | `false` | 启用复选框多选，触发器以标签显示选中项。 |
| `disabled` | `boolean` | `false` | 禁用触发器、下拉交互、键盘切换与清空。 |
| `placeholder` | `string` | `'请选择'` | 没有可显示的选中 label 时的占位文本。 |
| `searchable` | `boolean` | `true` | 显示搜索框，文本作为 `filterText` 传给内部 `TxTree`。 |
| `clearable` | `boolean` | `true` | 有选中项且未禁用时显示清空按钮。 |
| `placement` | `PopoverPlacement` | `'bottom-start'` | 下拉层的位置。 |
| `dropdownOffset` | `number` | `6` | 下拉层与触发器的距离。 |
| `dropdownWidth` | `number` | `0` | 下拉层宽度；`0` 交给 `TxPopover` 决定。 |
| `dropdownMaxWidth` | `number` | `480` | 下拉层最大宽度。 |
| `dropdownMaxHeight` | `number` | `320` | 下拉树最大高度，超出后滚动。 |
| `defaultExpandedKeys` | `Array<string \| number>` | `[]` | 内部 `TxTree` 的初始展开 key。 |

### 事件

| 事件名 | 参数 | 说明 |
|------|------|------|
| `update:modelValue` | `value: TreeSelectValue` | 选择、清空或调用 `setValue()` 后触发。 |
| `change` | `value: TreeSelectValue` | 紧随 `update:modelValue`，值相同。 |
| `open` | - | 下拉层打开时触发。 |
| `close` | - | 下拉层关闭时触发。 |

### 插槽

| 插槽名 | 参数 | 说明 |
|------|------|------|
| `node` | `{ node, level, expanded, selected }` | 替换行内的节点标签区；箭头、复选框、缩进与点击仍由组件处理。 |

### 暴露方法

| 名称 | 类型 | 说明 |
|------|------|------|
| `open()` | `() => void` | 打开下拉层。 |
| `close()` | `() => void` | 关闭下拉层。 |
| `toggle()` | `() => void` | 切换下拉层。 |
| `focus()` | `() => void` | 聚焦 combobox 触发器。 |
| `blur()` | `() => void` | 使 combobox 触发器失焦。 |
| `clear()` | `() => void` | 未禁用时清空：单选派发 `undefined`，多选派发 `[]`。 |
| `setValue(value)` | `(value: TreeSelectValue) => void` | 经 `update:modelValue` 与 `change` 派发传入值，不校验它是否在 `nodes` 中。 |
| `getValue()` | `() => TreeSelectValue` | 返回当前的 `modelValue`。 |
| `getCheckedKeys()` | `() => Array<string \| number>` | 以数组返回选中 key，单选模式亦然。 |

### 类型

:::TuffCodeBlock{lang="ts"}
---
code: |
  type TreeSelectValue = string | number | Array<string | number> | undefined

  interface TreeSelectNode {
    key: string | number // 稳定唯一，用作选中值
    label: string // 节点文本、默认搜索目标与触发器文本
    disabled?: boolean // 禁止选择该节点
    children?: TreeSelectNode[]
  }
---
:::

## 概述

- 触发器是可聚焦的 `role="combobox"`（`aria-haspopup="tree"`，`aria-controls` 指向浮层），浮层内是 `role="tree"` 的 `TxTree`；Enter 与 Space 开合下拉层，Escape 关闭。
- 单选选中后关闭下拉层，清空为 `undefined`；多选保持打开，清空为 `[]`。
- 禁用节点不可选，但有子节点时仍可展开。
- 搜索使用 `TxTree` 默认的 label 过滤，不支持自定义 `filterMethod` 或受控 `expandedKeys`；需要领域搜索时在外层组合，或直接用 `TxTree`。
- 触发器文本从当前 `nodes` 解析；未知的选中 key 仍留在选中集合中，但不显示文本。
- `setValue()` 只派发事件，`modelValue` 仍由父级经 `v-model` 持有；常规代码优先用 `v-model`。

## 技术实现

- 下拉层由 `TxPopover` 承载，位置与宽度属性透传给它；树复用 `TxTree`，只传入 `defaultExpandedKeys`、`filterText` 与 `multiple`。
- 源码：`packages/tuffex/packages/components/src/tree-select/`。

<TuffDocSourceLink />
