vue 实现div拖动排序
实现原理
通过HTML5的拖放API(Drag and Drop)结合Vue的数据绑定特性实现。主要利用draggable属性、dragstart、dragover、drop等事件完成元素位置交换。
基础实现步骤
安装依赖(如需要)
npm install vuedraggable
使用原生HTML5 API实现
<template>
<div
v-for="(item, index) in list"
:key="item.id"
draggable="true"
@dragstart="handleDragStart(index)"
@dragover.prevent="handleDragOver(index)"
@drop="handleDrop(index)"
>
{{ item.text }}
</div>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
],
draggedIndex: null
}
},
methods: {
handleDragStart(index) {
this.draggedIndex = index
},
handleDragOver(index) {
if (this.draggedIndex !== index) {
const draggedItem = this.list[this.draggedIndex]
this.list.splice(this.draggedIndex, 1)
this.list.splice(index, 0, draggedItem)
this.draggedIndex = index
}
},
handleDrop() {
this.draggedIndex = null
}
}
}
</script>
使用vuedraggable库
更简单的实现方式:
<template>
<draggable
v-model="list"
@end="onDragEnd"
>
<div v-for="item in list" :key="item.id">
{{ item.text }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
list: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
]
}
},
methods: {
onDragEnd() {
console.log('排序完成', this.list)
}
}
}
</script>
样式优化
添加拖拽时的视觉反馈:
[draggable="true"] {
cursor: move;
user-select: none;
}
.drag-over {
border: 2px dashed #000;
}
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
进阶功能
实现跨容器拖拽(多个列表间排序):
<draggable
v-model="listA"
group="shared"
@change="log"
>
<!-- 列表A内容 -->
</draggable>
<draggable
v-model="listB"
group="shared"
@change="log"
>
<!-- 列表B内容 -->
</draggable>
注意事项
- 移动端需要额外处理touch事件
- 复杂数据结构需要深拷贝避免直接修改
- 大型列表建议使用虚拟滚动优化性能
- 拖拽动画可以使用transition-group增强体验







