拖拽式编程vue实现
拖拽式编程在 Vue 中的实现方法
使用第三方库(如 vuedraggable)
安装 vuedraggable 库:
npm install vuedraggable
在 Vue 组件中引入并使用:

<template>
<draggable v-model="items" group="tasks" @end="onDragEnd">
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable';
export default {
components: { draggable },
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
};
},
methods: {
onDragEnd() {
console.log('拖拽完成');
}
}
};
</script>
原生 HTML5 拖拽 API 实现
通过 HTML5 的 draggable 属性和事件实现基础拖拽功能:

<template>
<div
v-for="item in items"
:key="item.id"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent
@drop="handleDrop($event, item)"
>
{{ item.name }}
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
],
draggedItem: null
};
},
methods: {
handleDragStart(event, item) {
this.draggedItem = item;
event.dataTransfer.effectAllowed = 'move';
},
handleDrop(event, targetItem) {
if (this.draggedItem === targetItem) return;
const draggedIndex = this.items.indexOf(this.draggedItem);
const targetIndex = this.items.indexOf(targetItem);
this.items.splice(draggedIndex, 1);
this.items.splice(targetIndex, 0, this.draggedItem);
}
}
};
</script>
自定义指令实现
创建 Vue 自定义指令处理拖拽逻辑:
<template>
<div v-draggable v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</template>
<script>
export default {
directives: {
draggable: {
inserted(el) {
el.draggable = true;
el.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', el.textContent);
});
}
}
},
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
};
}
};
</script>
注意事项
- 跨组件拖拽时需使用
group属性(vuedraggable) - 移动端兼容性需额外处理触摸事件
- 复杂场景可结合
Vuex管理拖拽状态 - 性能优化:对于大量数据使用虚拟滚动
进阶功能示例
实现拖拽排序与位置交换:
<template>
<div class="container">
<div
v-for="(item, index) in items"
:key="item.id"
draggable="true"
@dragstart="dragStart(index)"
@dragover.prevent
@dragenter="dragEnter(index)"
@dragend="dragEnd"
@drop="drop"
:class="{ 'dragging': currentDragIndex === index }"
>
{{ item.name }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [/* ... */],
currentDragIndex: null,
draggedIndex: null
};
},
methods: {
dragStart(index) {
this.draggedIndex = index;
},
dragEnter(index) {
this.currentDragIndex = index;
},
dragEnd() {
this.currentDragIndex = null;
},
drop() {
if (this.draggedIndex !== this.currentDragIndex) {
const movedItem = this.items.splice(this.draggedIndex, 1)[0];
this.items.splice(this.currentDragIndex, 0, movedItem);
}
}
}
};
</script>
<style>
.dragging {
opacity: 0.5;
border: 2px dashed #ccc;
}
</style>






