Tree 树形控件
基础用法
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
const data = ref([
{
value: '选项1',
key: '1',
children: [
{
value: '选项1-1',
key: '1-1',
},
{
value: '选项1-2',
key: '1-2',
children: [
{
value: '选项1-2-1',
key: '1-2-1',
},
],
},
],
},
{
value: '选项2',
key: '2',
children: [
{
value: '选项2-1',
key: '2-1',
},
],
},
])
</script>
<template>
<yy-tree :data="data" />
</template>
属性重命名
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
const data = ref([
{
anyValue: '选项1',
anyKey: '1',
children: [
{
anyValue: '选项1-1',
anyKey: '1-1',
},
{
anyValue: '选项1-2',
anyKey: '1-2',
children: [
{
anyValue: '选项1-2-1',
anyKey: '1-2-1',
},
],
},
],
},
{
anyValue: '选项2',
anyKey: '2',
children: [
{
anyValue: '选项2-1',
anyKey: '2-1',
},
],
},
] as any[])
</script>
<template>
<yy-tree :data="data" key-field="anyKey" value-field="anyValue" />
</template>
缩进宽度
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
const data = ref([
{
value: '选项1',
key: '1',
children: [
{
value: '选项1-1',
key: '1-1',
},
{
value: '选项1-2',
key: '1-2',
children: [
{
value: '选项1-2-1',
key: '1-2-1',
},
],
},
],
},
{
value: '选项2',
key: '2',
children: [
{
value: '选项2-1',
key: '2-1',
},
],
},
])
</script>
<template>
<yy-tree :data="data" :indent-width="42" />
</template>
默认展开
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
import { createData } from './utils'
const data1 = ref<any[]>([])
data1.value.push(...(createData(3, 3) as any[]))
const expandedKeys = ref(['0', '0-0'])
</script>
<template>
<yy-tree :data="data1" :default-expanded-keys="expandedKeys" />
</template>
可选择
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
const data = ref([
{
value: '选项1',
key: '1',
children: [
{
value: '选项1-1',
key: '1-1',
},
{
value: '选项1-2',
key: '1-2',
children: [
{
value: '选项1-2-1',
key: '1-2-1',
},
],
},
],
},
{
value: '选项2',
key: '2',
children: [
{
value: '选项2-1',
key: '2-1',
},
],
},
])
const selectedKeys = ref(['1'])
</script>
<template>
<yy-flex vertical>
<yy-p>单选模式:</yy-p>
<yy-tree v-model:selected-keys="selectedKeys" :data="data" selectable />
<yy-p>多选模式:</yy-p>
<yy-tree :data="data" selectable multiple />
</yy-flex>
</template>
可拖拽
查看示例
vue
<script setup lang="ts">
import type { TreeOption } from '@yy-craft/components/tree'
import { getChildren } from '@yy-craft/components/tree/src/utils'
import { ref } from 'vue'
const data = ref([
{
value: '选项1',
key: '1',
children: [
{
value: '选项1-1',
key: '1-1',
},
{
value: '选项1-2',
key: '1-2',
children: [
{
value: '选项1-2-1',
key: '1-2-1',
},
],
},
],
},
{
value: '选项2',
key: '2',
children: [
{
value: '选项2-1',
key: '2-1',
},
],
},
] as TreeOption[])
function onDrag(value: {
dragNode: TreeOption
dragNodeParent: TreeOption | null
dropNode: TreeOption | null
position: number
}) {
const { dragNode, dragNodeParent, dropNode, position } = value
// *切记先添加再删除
const dropNodePool = getChildren(data.value, dropNode)
const dragNodePool = getChildren(data.value, dragNodeParent)
if (dropNodePool === dragNodePool) {
// 同数组操作
const index = dragNodePool.findIndex(item => item.key === dragNode.key)
if (position - 1 === index)
return
dropNodePool.splice(position, 0, dragNode)
dropNodePool.splice(position - 1 > index ? index : index + 1, 1)
}
else {
dropNodePool.splice(position, 0, dragNode)
const index = dragNodePool.findIndex(item => item.key === dragNode.key)
dragNodePool.splice(index, 1)
}
data.value = [...data.value]
}
</script>
<template>
<yy-tree :data="data" draggable @drag="onDrag" />
</template>
动态加载
查看示例
vue
<script setup lang="ts">
import type { TreeOption } from '@yy-craft/components/tree'
import { ref } from 'vue'
const data = ref([
{
value: '根节点',
key: '0',
isLeaf: false,
},
] as TreeOption[])
function onLoad(node: TreeOption) {
return new Promise<void>((resolve) => {
setTimeout(() => {
const children = [
{
value: `节点 ${node.key}-0`,
key: `${node.key}-0`,
isLeaf: false,
},
{
value: `节点 ${node.key}-1`,
key: `${node.key}-1`,
isLeaf: false,
},
] as any[]
node.children = children
resolve()
}, 1000)
})
}
</script>
<template>
<yy-tree :data="data" :on-load="onLoad" />
</template>
虚拟滚动
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
import { createData } from './utils'
// 生成大量数据
const data = ref(createData(3, 10)!)
const defaultExpandedKeys = ref([] as string[])
function add(prefix?: string) {
for (let i = 0; i < 10; i++) {
defaultExpandedKeys.value.push(`${prefix ? `${prefix}-` : ''}${i}`)
if (!prefix) {
add(`${i}`)
}
}
}
add()
</script>
<template>
<yy-tree
:data="data"
virtual-scroll
:default-expanded-keys="defaultExpandedKeys"
:virtual-list-props="{ wrapperMaxSize: 300 }"
/>
</template>
传递插槽
查看示例
vue
<script setup lang="ts">
import { ref } from 'vue'
const data = ref([
{
value: '选项1',
key: '1',
children: [
{
value: '选项1-1',
key: '1-1',
},
{
value: '选项1-2',
key: '1-2',
children: [
{
value: '选项1-2-1',
key: '1-2-1',
},
],
},
],
},
{
value: '选项2',
key: '2',
children: [
{
value: '选项2-1',
key: '2-1',
},
],
},
])
</script>
<template>
<yy-tree :data="data">
<template #default="{ node }">
<div>我是自定义的内容 {{ node.key }}</div>
</template>
</yy-tree>
</template>
Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
data | 展示数据 | TreeOption[] | - |
valueField | 节点值的字段名 | string | 'value' |
keyField | 节点键的字段名 | string | 'key' |
defaultExpandedKeys | 默认展开的节点 | string[] | - |
onLoad | 加载子节点的函数 | (node: TreeOption) => Promise<any> | - |
selectable | 是否可选择 | boolean | false |
multiple | 是否可多选 | boolean | false |
selectedKeys | 选中的节点 | string[] | - |
indentWidth | 缩进宽度 | number | 21 |
draggable | 是否可拖拽 | boolean | false |
virtualScroll | 是否启用虚拟滚动 | boolean | false |
virtualListProps | 虚拟列表配置 | { wrapperMaxSize?: number } | - |
scrollbarProps | 滚动条配置: 仅在虚拟滚动时生效 | ScrollbarProps | - |
Events
事件名 | 说明 | 回调参数 |
---|---|---|
drag | 拖拽完成时触发 | (info: { dragNode: TreeOption, dragNodeParent: TreeOption | null, dropNode: TreeOption | null, position: number }) => void |
TreeOption 数据结构
ts
interface TreeOption {
value: string | number // 节点值
key: string // 节点唯一标识
children?: TreeOption[] // 子节点
isLeaf?: boolean // 是否是叶子节点
[key: string]: any // 其他自定义属性
}