vue实现拖动
Vue实现拖动功能
使用HTML5拖放API
在Vue中可以利用HTML5原生拖放API实现基础拖动功能。需要监听dragstart、dragover和drop事件。
<template>
<div
draggable="true"
@dragstart="handleDragStart"
@dragover.prevent
@drop="handleDrop">
可拖动元素
</div>
</template>
<script>
export default {
methods: {
handleDragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id)
},
handleDrop(e) {
const id = e.dataTransfer.getData('text/plain')
const draggableElement = document.getElementById(id)
e.target.appendChild(draggableElement)
}
}
}
</script>
使用第三方库vuedraggable
对于复杂场景推荐使用vuedraggable库,它基于Sortable.js实现,支持列表排序、跨列表拖动等功能。
安装依赖:
npm install vuedraggable
基本用法:
<template>
<draggable
v-model="list"
@end="onDragEnd">
<div v-for="item in list" :key="item.id">
{{ item.name }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
list: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
}
},
methods: {
onDragEnd() {
console.log('拖动结束', this.list)
}
}
}
</script>
自定义拖动指令
可以通过Vue自定义指令实现更灵活的拖动控制:
Vue.directive('drag', {
bind(el, binding) {
let posX = 0, posY = 0
el.style.position = 'absolute'
el.style.cursor = 'move'
el.addEventListener('mousedown', startDrag)
function startDrag(e) {
posX = e.clientX - el.getBoundingClientRect().left
posY = e.clientY - el.getBoundingClientRect().top
document.addEventListener('mousemove', dragElement)
document.addEventListener('mouseup', stopDrag)
}
function dragElement(e) {
el.style.left = (e.clientX - posX) + 'px'
el.style.top = (e.clientY - posY) + 'px'
}
function stopDrag() {
document.removeEventListener('mousemove', dragElement)
document.removeEventListener('mouseup', stopDrag)
}
}
})
移动端触摸支持
针对移动设备需要添加触摸事件处理:

<div
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd">
可触摸拖动元素
</div>
<script>
export default {
data() {
return {
startX: 0,
startY: 0
}
},
methods: {
handleTouchStart(e) {
this.startX = e.touches[0].clientX
this.startY = e.touches[0].clientY
},
handleTouchMove(e) {
const moveX = e.touches[0].clientX - this.startX
const moveY = e.touches[0].clientY - this.startY
e.target.style.transform = `translate(${moveX}px, ${moveY}px)`
},
handleTouchEnd() {
// 拖动结束处理
}
}
}
</script>
性能优化建议
对于大量可拖动元素,使用虚拟滚动技术减少DOM操作。考虑使用transition-group实现平滑的动画效果,避免频繁的直接DOM操作。






