vue实现树形拖拽
Vue 实现树形拖拽的方法
使用 vue-draggable 插件
安装 vue-draggable 插件:
npm install vuedraggable --save
在组件中引入并使用:
<template>
<draggable v-model="treeData" group="nodes" @end="onDragEnd">
<div v-for="(item, index) in treeData" :key="item.id">
{{ item.name }}
<draggable v-if="item.children" v-model="item.children" group="nodes">
<div v-for="child in item.children" :key="child.id">
{{ child.name }}
</div>
</draggable>
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
treeData: [
{ id: 1, name: 'Node 1', children: [
{ id: 11, name: 'Node 1-1' }
]},
{ id: 2, name: 'Node 2' }
]
}
},
methods: {
onDragEnd() {
console.log('Drag end', this.treeData)
}
}
}
</script>
使用 Element UI 的树形组件
安装 Element UI:
npm install element-ui --save
实现拖拽功能:
<template>
<el-tree
:data="treeData"
draggable
@node-drop="handleDrop"
/>
</template>
<script>
export default {
data() {
return {
treeData: [
{ label: 'Node 1', children: [
{ label: 'Node 1-1' }
]},
{ label: 'Node 2' }
]
}
},
methods: {
handleDrop(draggingNode, dropNode, dropType) {
console.log('Drop event', draggingNode, dropNode, dropType)
}
}
}
</script>
自定义实现拖拽功能
通过 HTML5 的拖拽 API 实现:
<template>
<div class="tree">
<div
v-for="item in treeData"
:key="item.id"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent
@drop="handleDrop($event, item)"
>
{{ item.name }}
<div v-if="item.children" class="children">
<div
v-for="child in item.children"
:key="child.id"
draggable="true"
@dragstart="handleDragStart($event, child)"
@dragover.prevent
@drop="handleDrop($event, child)"
>
{{ child.name }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{ id: 1, name: 'Node 1', children: [
{ id: 11, name: 'Node 1-1' }
]},
{ id: 2, name: 'Node 2' }
],
draggingNode: null
}
},
methods: {
handleDragStart(event, node) {
this.draggingNode = node
event.dataTransfer.setData('text/plain', node.id)
},
handleDrop(event, targetNode) {
if (this.draggingNode === targetNode) return
// 实现节点移动逻辑
console.log('Move', this.draggingNode, 'to', targetNode)
}
}
}
</script>
<style>
.tree {
user-select: none;
}
.children {
margin-left: 20px;
}
</style>
使用 vue-tree-dnd 插件
专门用于树形拖拽的插件:
npm install vue-tree-dnd --save
基本用法:
<template>
<tree :data="treeData" :options="options" @change="onTreeChange"/>
</template>
<script>
import { Tree } from 'vue-tree-dnd'
export default {
components: { Tree },
data() {
return {
treeData: [
{ id: 1, name: 'Node 1', children: [
{ id: 11, name: 'Node 1-1' }
]},
{ id: 2, name: 'Node 2' }
],
options: {
drag: true,
drop: true
}
}
},
methods: {
onTreeChange(newTree) {
this.treeData = newTree
}
}
}
</script>
注意事项
- 树形数据结构需要包含唯一标识符(如 id)
- 拖拽时需要处理父子节点关系
- 移动节点后需要更新整个树结构
- 复杂操作可能需要递归处理数据
以上方法可以根据项目需求选择合适的方式实现树形拖拽功能。







