Skip to content

Tree 树形控件

用清晰的层级结构展示信息,可展开或折叠。

基础用法

基础的树形结构展示。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data" />
</template>

<script setup>
import { ref } from 'vue'

const data = ref([
  {
    value: 1,
    label: '一级 1',
    children: [
      {
        value: 4,
        label: '二级 1-1',
        children: [
          { value: 9, label: '三级 1-1-1' },
          { value: 10, label: '三级 1-1-2' }
        ]
      }
    ]
  },
  {
    value: 2,
    label: '一级 2',
    children: [
      { value: 5, label: '二级 2-1' },
      { value: 6, label: '二级 2-2' }
    ]
  },
  {
    value: 3,
    label: '一级 3',
    children: [
      { value: 7, label: '二级 3-1' },
      { value: 8, label: '二级 3-2' }
    ]
  }
])
</script>

可选择

适用于需要选择层级时使用。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data" selectable highlight-current />
</template>

复选框

适用于需要勾选节点时使用,默认父子节点联动。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data" show-checkbox />
</template>

复选框不联动

设置 check-strictly 属性后父子节点不再关联。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data" show-checkbox check-strictly />
</template>

懒加载

通过 lazy 属性开启懒加载模式,通过 load 方法加载子节点数据。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data" lazy :load="loadNode" />
</template>

<script setup>
import { ref } from 'vue'

const data = ref([
  { value: 1, label: '一级 1' },
  { value: 2, label: '一级 2' },
  { value: 3, label: '一级 3' }
])

const loadNode = (node, resolve) => {
  if (node.level === 0) return

  setTimeout(() => {
    const data = [
      { value: `${node.value}-1`, label: `${node.label}-子节点1`, isLeaf: true },
      { value: `${node.value}-2`, label: `${node.label}-子节点2`, isLeaf: true }
    ]
    resolve(data)
  }, 1000)
}
</script>

默认展开和默认选中

使用 default-expanded-keysdefault-selected-keys 设置默认展开和默认选中的节点。

一级 1
一级 2
二级 2-1
二级 2-2
一级 3
vue
<template>
  <x-tree
    :data="data"
    :default-expanded-keys="[2, 5]"
    :default-selected-keys="[5]"
    highlight-current
  />
</template>

默认勾选

使用 default-checked-keys 设置默认勾选的节点。

一级 1
二级 1-1
三级 1-1-1
三级 1-1-2
一级 2
一级 3
vue
<template>
  <x-tree
    :data="data"
    show-checkbox
    :default-expanded-keys="[1, 4]"
    :default-checked-keys="[9]"
  />
</template>

禁用状态

通过节点的 disabled 属性禁用节点。

一级 1 (禁用)
一级 2
vue
<template>
  <x-tree :data="data" show-checkbox />
</template>

<script setup>
const data = [
  {
    value: 1,
    label: '一级 1',
    disabled: true,
    children: [
      { value: 4, label: '二级 1-1' }
    ]
  },
  {
    value: 2,
    label: '一级 2',
    children: [
      { value: 5, label: '二级 2-1', disabled: true },
      { value: 6, label: '二级 2-2' }
    ]
  }
]
</script>

自定义节点内容

使用默认插槽自定义节点内容。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data">
    <template #default="{ node }">
      <span class="custom-tree-node">
        <span>{{ node.label }}</span>
        <span>
          <button size="small" @click.stop>编辑</button>
          <button size="small" @click.stop>删除</button>
        </span>
      </span>
    </template>
  </x-tree>
</template>

<style>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>

节点过滤

通过 filter 方法过滤树节点。

一级 1
一级 2
一级 3
vue
<template>
  <input v-model="filterText" placeholder="输入关键字过滤" />
  <x-tree ref="treeRef" :data="data" :filter-node-method="filterNode" />
</template>

<script setup>
import { ref, watch } from 'vue'

const filterText = ref('')
const treeRef = ref()

const filterNode = (value, data, node) => {
  if (!value) return true
  return data.label.includes(value)
}

watch(filterText, (val) => {
  treeRef.value?.filter(val)
})
</script>

手风琴模式

通过 accordion 属性开启手风琴模式,同一级节点只能展开一个。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree :data="data" accordion />
</template>

可拖拽节点

通过 draggable 属性开启节点拖拽功能。

一级 1
一级 2
一级 3
vue
<template>
  <x-tree
    :data="data"
    draggable
    @node-drag-start="handleDragStart"
    @node-drop="handleDrop"
  />
</template>

<script setup>
const handleDragStart = (node, event) => {
  console.log('开始拖拽:', node.label)
}

const handleDrop = (dragNode, dropNode, dropType, event) => {
  console.log('拖拽完成:', dragNode.label, '->', dropNode.label, dropType)
}
</script>

属性配置

使用 props 属性可以自定义节点字段名。

一级 1
一级 2
vue
<template>
  <x-tree :data="data" :props="props" />
</template>

<script setup>
const props = {
  label: 'name',
  children: 'zones'
}

const data = [
  {
    value: 1,
    name: '一级 1',
    zones: [
      { value: 4, name: '二级 1-1' }
    ]
  }
]
</script>

API

Props

属性说明类型默认值
data树节点数据TreeNodeData[][]
empty-text空数据提示文本string'暂无数据'
node-key节点唯一标识字段名string'value'
props字段映射配置object{}
render-after-expand是否展开后渲染子节点booleantrue
load懒加载方法Function
highlight-current是否高亮当前节点booleanfalse
check-on-click-node点击节点时是否勾选booleanfalse
auto-expand-parent展开节点时是否自动展开父节点booleantrue
default-expanded-keys默认展开的节点 keyarray[]
default-checked-keys默认勾选的节点 keyarray[]
default-selected-keys默认选中的节点 keyarray[]
expanded-keys展开的节点 key(受控)array
checked-keys勾选的节点 key(受控)array
selected-keys选中的节点 key(受控)array
check-strictly父子节点是否不关联booleanfalse
lazy是否懒加载booleanfalse
draggable是否可拖拽booleanfalse
allow-drag是否允许拖拽判断函数Function
allow-drop是否允许放置判断函数Function
accordion是否手风琴模式booleanfalse
indent缩进number16
icon自定义图标string
expand-on-click-node点击节点是否展开booleantrue
show-line是否显示连接线booleanfalse
show-checkbox是否显示复选框booleanfalse
selectable是否可选择booleanfalse
size尺寸'large' | 'default' | 'small''default'

Events

事件名说明回调参数
node-click节点点击时触发(data, node, instance)
node-contextmenu右键点击时触发(event, data, node)
check-change勾选变化时触发(data, checked, indeterminate)
check勾选时触发(data, { checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys })
current-change当前节点变化时触发(data, node)
node-expand节点展开时触发(data, node, instance)
node-collapse节点收起时触发(data, node, instance)
node-drag-start拖拽开始时触发(node, event)
node-drag-enter拖拽进入节点时触发(node, event)
node-drag-leave拖拽离开节点时触发(node, event)
node-drag-over拖拽悬停时触发(node, event)
node-drag-end拖拽结束时触发(node, event)
node-drop拖拽放置时触发(dragNode, dropNode, dropType, event)

Methods

方法名说明参数
filter过滤节点(value: string)
getNode获取节点实例(key)
setCurrentKey设置当前节点(key)
getCurrentKey获取当前节点 key
getCurrentNode获取当前节点
getCheckedNodes获取勾选的节点(leafOnly)
getCheckedKeys获取勾选的 keys(leafOnly)
setCheckedKeys设置勾选的 keys(keys)
setChecked设置节点勾选状态(key, checked, deep)
getHalfCheckedNodes获取半选节点
getHalfCheckedKeys获取半选 keys
getSelectedNodes获取选中节点
setSelectedKeys设置选中的 keys(keys)
expandAll展开所有节点
collapseAll收起所有节点
updateKeyChildren更新子节点(key, data)
remove删除节点(key)
append追加节点(data, parentKey)
insertBefore在节点前插入(data, key)
insertAfter在节点后插入(data, key)

Slots

插槽名说明参数
default自定义节点内容{ node, data }
empty无数据时的内容

TreeNodeData

属性说明类型
value节点唯一标识string | number
label节点标签string
children子节点TreeNodeData[]
disabled是否禁用boolean
isLeaf是否为叶子节点boolean

基于 MIT 许可发布