Skip to content

节点操作

自定义节点

有两种自定义节点的方式:

  1. 传入具名插槽 node
  2. 使用 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>

拖拽

启用 draggabledroppable 可实现拖拽功能

查看代码
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>