Skip to content

TreeSelect 树形选择

含有下拉菜单的树形选择器,结合了 el-treeel-select 两个组件的功能。

ts
import { createApp } from 'vue'
import { TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'

const app = createApp()
app.use(ElTreeSelect)

基础用法

树状选择器

<template>
  <el-tree-select
    v-model="value"
    :data="data"
    :render-after-expand="false"
    style="width: 240px"
  />
  <el-divider />
  show checkbox:
  <el-tree-select
    v-model="value"
    :data="data"
    :render-after-expand="false"
    show-checkbox
    style="width: 240px"
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Divider as ElDivider, TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


const value = ref()

const data = [
  {
    value: '1',
    label: 'Level one 1',
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        children: [
          {
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    value: '3',
    label: 'Level one 3',
    children: [
      {
        value: '3-1',
        label: 'Level two 3-1',
        children: [
          {
            value: '3-1-1',
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        value: '3-2',
        label: 'Level two 3-2',
        children: [
          {
            value: '3-2-1',
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
]
</script>

选择任意级别

当属性 check-strictly=true 时,任何节点都可以被选择,否则只有子节点可被选择。

TIP

TIP 当使用 show-checkbox 时,由于 check-on-click-node 默认值是 false,这时候只能通过 checkbox 来选中,当然您也可以将其设置成 true,这样点击整个 node 都可以用来完成选择

WARNING

WARNING 在使用 show-checkbox 时,因为 check-on-click-leaf 默认值为 true, 最后一个树节点可以通过点击节点进行勾选。

<template>
  <el-tree-select
    v-model="value"
    :data="data"
    check-strictly
    :render-after-expand="false"
    style="width: 240px"
  />
  <el-divider />
  show checkbox:
  <el-tree-select
    v-model="value"
    :data="data"
    check-strictly
    :render-after-expand="false"
    show-checkbox
    style="width: 240px"
  />
  <el-divider />
  show checkbox with `check-on-click-node`:
  <el-tree-select
    v-model="value"
    :data="data"
    check-strictly
    :render-after-expand="false"
    show-checkbox
    check-on-click-node
    style="width: 240px"
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Divider as ElDivider, TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


const value = ref()

const data = [
  {
    value: '1',
    label: 'Level one 1',
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        children: [
          {
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    value: '3',
    label: 'Level one 3',
    children: [
      {
        value: '3-1',
        label: 'Level two 3-1',
        children: [
          {
            value: '3-1-1',
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        value: '3-2',
        label: 'Level two 3-2',
        children: [
          {
            value: '3-2-1',
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
]
</script>

多选

通过点击或复选框选择多个选项。

<template>
  <el-tree-select
    v-model="value"
    :data="data"
    multiple
    :render-after-expand="false"
    style="width: 240px"
  />
  <el-divider />
  show checkbox:
  <el-tree-select
    v-model="value"
    :data="data"
    multiple
    :render-after-expand="false"
    show-checkbox
    style="width: 240px"
  />
  <el-divider />
  show checkbox with `check-strictly`:
  <el-tree-select
    v-model="valueStrictly"
    :data="data"
    multiple
    :render-after-expand="false"
    show-checkbox
    check-strictly
    check-on-click-node
    style="width: 240px"
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Divider as ElDivider, TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


const value = ref()
const valueStrictly = ref()

const data = [
  {
    value: '1',
    label: 'Level one 1',
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        children: [
          {
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    value: '3',
    label: 'Level one 3',
    children: [
      {
        value: '3-1',
        label: 'Level two 3-1',
        children: [
          {
            value: '3-1-1',
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        value: '3-2',
        label: 'Level two 3-2',
        children: [
          {
            value: '3-2-1',
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
]
</script>

禁用选项

使用 disabled 字段禁用选项。

<template>
  <el-tree-select v-model="value" :data="data" style="width: 240px" />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


const value = ref()

const data = [
  {
    value: '1',
    label: 'Level one 1',
    disabled: true,
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        disabled: true,
        children: [
          {
            disabled: true,
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    value: '3',
    label: 'Level one 3',
    children: [
      {
        value: '3-1',
        label: 'Level two 3-1',
        children: [
          {
            value: '3-1-1',
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        value: '3-2',
        label: 'Level two 3-2',
        children: [
          {
            value: '3-2-1',
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
]
</script>

可筛选

使用关键字筛选或自定义筛选方法。 filterMethod可以自定义数据筛选的方法, filterNodeMethod可以自定义节点数据筛选的方法。

<template>
  <el-tree-select
    v-model="value"
    :data="data"
    filterable
    style="width: 240px"
  />
  <el-divider />
  filter method:
  <el-tree-select
    v-model="value"
    :data="data"
    :filter-method="filterMethod"
    filterable
    style="width: 240px"
  />
  <el-divider />
  filter node method:
  <el-tree-select
    v-model="value"
    :data="data"
    :filter-node-method="filterNodeMethod"
    filterable
    style="width: 240px"
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Divider as ElDivider, TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


interface TreeSelectOption {
  value: string
  label: string
  children?: TreeSelectOption[]
}

const value = ref<string>()

const sourceData: TreeSelectOption[] = [
  {
    value: '1',
    label: 'Level one 1',
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        children: [
          {
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    value: '3',
    label: 'Level one 3',
    children: [
      {
        value: '3-1',
        label: 'Level two 3-1',
        children: [
          {
            value: '3-1-1',
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        value: '3-2',
        label: 'Level two 3-2',
        children: [
          {
            value: '3-2-1',
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
]
const data = ref(sourceData)

const filterMethod = (value: string) => {
  data.value = [...sourceData].filter((item) => item.label.includes(value))
}

const filterNodeMethod = (value: string, data: TreeSelectOption) => data.label.includes(value)
</script>

自定义内容

自定义树节点的内容。

<template>
  <el-tree-select v-model="value" :data="data" style="width: 240px">
    <template #default="{ data: { label } }">
      {{ label }}<span style="color: gray">(suffix)</span>
    </template>
  </el-tree-select>
  <el-divider />
  use render content:
  <el-tree-select
    v-model="value"
    :data="data"
    :render-content="renderContent"
    style="width: 240px"
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import type { RenderContentFunction } from '@szhn/dh-design-pc'
import { Divider as ElDivider, TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


const value = ref<string | number>()

const renderContent: RenderContentFunction = (h, { data }) => {
  return h(
    'span',
    {
      style: {
        color: '#626AEF',
      },
    },
    data.label
  )
}

const data = [
  {
    value: '1',
    label: 'Level one 1',
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        children: [
          {
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    value: '3',
    label: 'Level one 3',
    children: [
      {
        value: '3-1',
        label: 'Level two 3-1',
        children: [
          {
            value: '3-1-1',
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        value: '3-2',
        label: 'Level two 3-2',
        children: [
          {
            value: '3-2-1',
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
]
</script>

懒加载

树节点懒加载,更加适合于数据量大的列表。

<template>
  <el-tree-select
    v-model="value"
    lazy
    :load="load"
    :props="props"
    style="width: 240px"
  />
  <el-divider />
  <VersionTag version="2.2.26" /> show lazy load label:
  <el-tree-select
    v-model="value2"
    lazy
    :load="load"
    :props="props"
    :cache-data="cacheData"
    style="width: 240px"
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Divider as ElDivider, TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


interface LazyNodeOption {
  value: number
  label: string
  isLeaf?: boolean
}

const value = ref<number>()
const value2 = ref(5)

const cacheData: LazyNodeOption[] = [{ value: 5, label: 'lazy load node5' }]

const props = {
  label: 'label',
  children: 'children',
  isLeaf: 'isLeaf',
}

let id = 0

const load = (node: { isLeaf?: boolean }, resolve: (data: LazyNodeOption[]) => void) => {
  if (node.isLeaf) return resolve([])

  setTimeout(() => {
    resolve([
      {
        value: ++id,
        label: `lazy load node${id}`,
      },
      {
        value: ++id,
        label: `lazy load node${id}`,
        isLeaf: true,
      },
    ])
  }, 400)
}
</script>

使用 node-key 属性

默认情况下,modelValue 会查找 value 键。 对于其他数据结构,必须提供 node-key 才能正常工作。

TIP

TIP node-key 在整个树中应该是唯一的。 value-key 与 node-key 具有相同的目标。 与 select 组件相反,tree-select 不能检索对象值。

<template>
  <el-tree-select
    v-model="value"
    style="width: 240px"
    :data="data"
    node-key="id"
    show-checkbox
    multiple
    default-expand-all
  />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { TreeSelect as ElTreeSelect } from '@szhn/dh-design-pc'


const value = ref([2])
const data = [
  {
    id: 1,
    label: 'Level one 1',
    children: [
      {
        id: 2,
        label: 'Level two 1-1',
      },
      {
        id: 3,
        label: 'Level two 1-2',
      },
    ],
  },
]
</script>

API

Attributes

属性对外暴露的方法事件插槽
treetreetreetree
selectselectselectselect

对外暴露的方法

事件名详情Type
treeRef 2.11.3Tree 组件实例TreeInstance
selectRef 2.11.3Select 组件实例SelectInstance
filter deprecated过滤所有树节点,过滤后的节点将被隐藏接收一个参数并指定为 filter-node-method 属性的第一个参数
updateKeyChildren deprecated为节点设置新数据,只有当设置 node-key 属性的时候才可用(key, data) 接收两个参数: 1. 节点的 key 2. 新数据
getCheckedNodes deprecated如果节点可以被选中,(show-checkboxtrue), 本方法将返回当前选中节点的数组(leafOnly, includeHalfChecked) 接收两个布尔类型参数: 1. 默认值为 false. 若参数为 true, 它将返回当前选中节点的子节点 2. 默认值为 false. 如果参数为 true, 返回值包含半选中节点数据
setCheckedNodes deprecated设置目前选中的节点,使用此方法必须设置 node-key 属性要选中的节点构成的数组
getCheckedKeys deprecated若节点可用被选中 (show-checkboxtrue), 它将返回当前选中节点 key 的数组(leafOnly) 接收一个布尔类型参数,默认为 false. 若参数为 true, 它将返回当前选中节点的子节点
setCheckedKeys deprecated设置目前选中的节点,使用此方法必须设置 node-key 属性(keys, leafOnly) 接收两个参数: 1. 一个需要被选中的多节点 key 的数组 2. 布尔类型的值 如果设置为 true,将只设置选中的叶子节点状态。 默认值是 false.
setChecked deprecated设置节点是否被选中, 使用此方法必须设置 node-key 属性(key/data, checked, deep) 接收三个参数: 1. 要选中的节点的 key 或者数据 2. 一个布尔类型参数表明是否选中. 3. 一个布尔类型参数表明是否递归选中子节点
getHalfCheckedNodes deprecated如果节点可用被选中 (show-checkboxtrue), 它将返回当前半选中的节点组成的数组:::
getHalfCheckedKeys deprecated若节点可被选中(show-checkboxtrue),则返回目前半选中的节点的 key 所组成的数组:::
getCurrentKey deprecated返回当前被选中节点的数据 (如果没有则返回 null):::
getCurrentNode deprecated返回当前被选中节点的数据 (如果没有则返回 null):::
setCurrentKey deprecated通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性(key, shouldAutoExpandParent=true) 1. 待被选节点的 key, 如果为 null, 取消当前选中的节点 2. 是否展开父节点
setCurrentNode deprecated设置节点为选中状态,使用此方法必须设置 node-key 属性(node, shouldAutoExpandParent=true) 1. 待被选中的节点 2. 是否展开父节点
getNode deprecated根据 data 或者 key 拿到 Tree 组件中的 node(data) 节点的 data 或 key
remove deprecated删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性(data) 要删除的节点的 data 或者 node 对象
append deprecated为 Tree 中的一个节点追加一个子节点(data, parentNode) 1. 要追加的子节点的 data 2. 父节点的 data, key 或 node
insertBefore deprecated在 Tree 中给定节点前插入一个节点(data, refNode) 1. 要增加的节点的 data 2. 参考节点的 data, key 或 node
insertAfter deprecated在 Tree 中给定节点后插入一个节点(data, refNode) 1. 要增加的节点的 data 2. 参考节点的 data, key 或 node
focus deprecated使选择器的输入框获取焦点Function
blur deprecated使选择器的输入框失去焦点,并隐藏下拉框Function
selectedLabel 2.8.5 deprecated获取当前选中的标签object