节点操作
自定义节点
有两种自定义节点的方式:
- 传入具名插槽
node
- 使用
render
Prop
查看代码
vue
<template> <VTree :data="data"> <template #node="{ node }"> <span :style="{ color: 'violet' }">{{ node.title }}</span> </template> </VTree> </template> <script setup lang="ts"> import { ref } from 'vue' import VTree from '@wsfe/vue-tree' const data = ref([ { title: 'node-1', id: 'node-1', children: [ { title: 'node-1-1', id: 'node-1-1', children: [ { title: 'node-1-1-1', id: 'node-1-1-1', }, { title: 'node-1-1-2', id: 'node-1-1-2', }, { title: 'node-1-1-3', id: 'node-1-1-3', }, ], }, { title: 'node-1-2', id: 'node-1-2', children: [ { title: 'node-1-2-1', id: 'node-1-2-1', }, { title: 'node-1-2-2', id: 'node-1-2-2', }, ], }, { title: 'node-1-3', id: 'node-1-3', children: [ { title: 'node-1-3-1', id: 'node-1-3-1', }, { title: 'node-1-3-2', id: 'node-1-3-2', }, ], }, ], }, { title: 'node-2', id: 'node-2', children: [ { title: 'node-2-1', id: 'node-2-1', children: [ { title: 'node-2-1-1', id: 'node-2-1-1', }, { title: 'node-2-1-2', id: 'node-2-1-2', }, ], }, ], }, ]) </script>
拖拽
启用 draggable
与 droppable
可实现拖拽功能
查看代码
vue
<template> <VTree :data="data" checkable draggable droppable /> </template> <script setup lang="ts"> import { ref } from 'vue' import VTree from '@wsfe/vue-tree' const data = ref([ { title: 'node-1', id: 'node-1', children: [ { title: 'node-1-1', id: 'node-1-1', children: [ { title: 'node-1-1-1', id: 'node-1-1-1', }, { title: 'node-1-1-2', id: 'node-1-1-2', }, { title: 'node-1-1-3', id: 'node-1-1-3', }, ], }, { title: 'node-1-2', id: 'node-1-2', children: [ { title: 'node-1-2-1', id: 'node-1-2-1', }, { title: 'node-1-2-2', id: 'node-1-2-2', }, ], }, { title: 'node-1-3', id: 'node-1-3', children: [ { title: 'node-1-3-1', id: 'node-1-3-1', }, { title: 'node-1-3-2', id: 'node-1-3-2', }, ], }, ], }, { title: 'node-2', id: 'node-2', children: [ { title: 'node-2-1', id: 'node-2-1', children: [ { title: 'node-2-1-1', id: 'node-2-1-1', }, { title: 'node-2-1-2', id: 'node-2-1-2', }, ], }, ], }, ]) </script>
节点新增与删除
- 调用树组件的
insertBefore
,insertAfter
方法,可在节点前后插入新的节点 - 调用树组件的
prepend
,append
方法,可插入新的节点到子节点列表的最前面或最后面 - 调用树组件的
remove
方法,可移除节点
查看代码
vue
<template> <VTree ref="tree" :data="data"> <template #node="{ node }"> <span>{{ node.title }}</span> <button @click="handleAdd(node)">Add sibling</button> <button @click="handleAppend(node)">Append child</button> <button @click="handleRemove(node)">Remove</button> </template> </VTree> </template> <script setup lang="ts"> import { ref } from 'vue' import VTree from '@wsfe/vue-tree' const tree = ref() let nodeAddCount = 0 let nodeAppendCount = 0 const handleAdd = (node) => { tree.value.insertAfter({ title: `node-added-${nodeAddCount}` }, node.id) nodeAddCount++ } const handleAppend = (node) => { tree.value.append({ title: `node-appended-${nodeAppendCount}` }, node.id) nodeAppendCount++ } const handleRemove = (node) => { tree.value.remove(node.id) } const data = ref([ { title: 'node-1', id: 'node-1', children: [ { title: 'node-1-1', id: 'node-1-1', children: [ { title: 'node-1-1-1', id: 'node-1-1-1', }, { title: 'node-1-1-2', id: 'node-1-1-2', }, { title: 'node-1-1-3', id: 'node-1-1-3', }, ], }, { title: 'node-1-2', id: 'node-1-2', children: [ { title: 'node-1-2-1', id: 'node-1-2-1', }, { title: 'node-1-2-2', id: 'node-1-2-2', }, ], }, { title: 'node-1-3', id: 'node-1-3', children: [ { title: 'node-1-3-1', id: 'node-1-3-1', }, { title: 'node-1-3-2', id: 'node-1-3-2', }, ], }, ], }, { title: 'node-2', id: 'node-2', children: [ { title: 'node-2-1', id: 'node-2-1', children: [ { title: 'node-2-1-1', id: 'node-2-1-1', }, { title: 'node-2-1-2', id: 'node-2-1-2', }, ], }, ], }, ]) </script> <style scoped> button { margin-left: 8px; border: 1px solid lightgray; border-radius: 4px; padding: 0 4px; font-size: 12px; line-height: 12px; height: 20px; } </style>
更新节点名称
调用树组件的 updateNode
方法可更新节点部分字段
调用 updateNodes
可批量更新
查看代码
vue
<template> <button @click="handleUpdateSingleNode">Update node-1</button> <button @click="handleUpdateMultipleNode">Update node-1 & node-2</button> <VTree ref="tree" /> </template> <script setup lang="ts"> import { computed, onMounted, ref } from 'vue' import VTree from '@wsfe/vue-tree' const tree = ref() const data = [ { title: 'node-1', id: 'node-1', children: [ { title: 'node-1-1', id: 'node-1-1', }, { title: 'node-1-2', id: 'node-1-2', }, ], }, { title: 'node-2', id: 'node-2', children: [ { title: 'node-2-1', id: 'node-2-1', }, ], }, ] onMounted(() => { tree.value.setData(data) }) const count = ref(0) const handleUpdateSingleNode = () => { count.value++ tree.value.updateNode('node-1', { title: `node-1 - ${count.value}` }) } const handleUpdateMultipleNode = () => { count.value++ tree.value.updateNodes([ { id: 'node-1', title: `node-1 - ${count.value}`, }, { id: 'node-2', title: `node-2 - ${count.value}`, }, ]) } </script> <style scoped> button { border: 1px solid lightgray; border-radius: 8px; padding-left: 10px; padding-right: 10px; margin-right: 20px; } </style>
更新自定义字段
调用树组件的 updateNode
方法更新自定义字段
查看代码
vue
<template> <button @click="handleUpdateCount">Update node-1 count</button> <VTree ref="tree"> <template #node="{ node }"> <span>{{ node.title }}</span> <span v-if="typeof node.count === 'number'"> Count: {{ node.count }} </span> </template> </VTree> </template> <script setup lang="ts"> import { onMounted, ref } from 'vue' import VTree from '@wsfe/vue-tree' const tree = ref() const data = [ { title: 'node-1', id: 'node-1', count: 0, children: [ { title: 'node-1-1', id: 'node-1-1', }, { title: 'node-1-2', id: 'node-1-2', }, ], }, { title: 'node-2', id: 'node-2', children: [ { title: 'node-2-1', id: 'node-2-1', }, ], }, ] onMounted(() => { tree.value.setData(data) }) const handleUpdateCount = () => { const key = 'node-1' const currentCount = tree.value.getNode(key).count tree.value.updateNode(key, { count: currentCount + 1 }) } </script> <style scoped> button { border: 1px solid lightgray; border-radius: 8px; padding-left: 10px; padding-right: 10px; margin-right: 20px; } </style>
重新加载子节点
调用 updateNode
传入新的 children
列表可以重新加载子节点
查看代码
vue
<template> <button @click="handleClearChildren">Clear node-1 children</button> <button @click="handleSetChildren">Set node-1 children</button> <button @click="handleUpdateChildren">Update node-1 children</button> <div :style="{ height: '300px' }"> <VTree ref="tree" checkable selectable /> </div> </template> <script setup lang="ts"> import { computed, onMounted, ref } from 'vue' import VTree from '@wsfe/vue-tree' const tree = ref() const children = Array.from({ length: 100000 }).map((_, i) => { return { title: `node-1-${i + 1}`, id: `node-1-${i + 1}`, } }) const data = [ { title: 'node-1', id: 'node-1', children, }, { title: 'node-2', id: 'node-2', children: [ { title: 'node-2-1', id: 'node-2-1', }, ], }, ] onMounted(() => { tree.value.setData(data) }) const handleSetChildren = () => { tree.value.updateNode('node-1', { children }) } const handleClearChildren = () => { tree.value.updateNode('node-1', { children: [] }) } const handleUpdateChildren = () => { tree.value.updateNode('node-1', { children: children.map((child) => { return { ...child, title: `${child.title} ${Date.now()}`, checked: true, } }) }) } </script> <style scoped> button { border: 1px solid lightgray; border-radius: 8px; padding-left: 10px; padding-right: 10px; margin-right: 20px; } </style>