前端实现拖拽功能vue
使用 HTML5 拖放 API 实现基础拖拽
在 Vue 中可以通过原生 HTML5 拖放 API 实现基础拖拽功能。需要为元素添加 draggable 属性,并监听相关事件:
<template>
<div
draggable="true"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
>
可拖拽元素
</div>
<div
@dragover.prevent
@drop="handleDrop"
>
放置区域
</div>
</template>
<script>
export default {
methods: {
handleDragStart(e) {
e.dataTransfer.setData('text/plain', '自定义数据')
},
handleDrop(e) {
const data = e.dataTransfer.getData('text/plain')
console.log('接收到的数据:', data)
}
}
}
</script>
使用第三方库 vue-draggable
对于更复杂的拖拽场景,推荐使用专门为 Vue 设计的拖拽库 vue-draggable:
安装依赖:
npm install vuedraggable
基本使用示例:
<template>
<draggable
v-model="list"
@start="dragStart"
@end="dragEnd"
>
<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: '项目1' },
{ id: 2, name: '项目2' }
]
}
}
}
</script>
实现自定义拖拽视觉效果
可以通过 CSS 和事件处理实现拖拽时的视觉效果:
.draggable-item {
transition: transform 0.2s;
}
.draggable-item.dragging {
opacity: 0.5;
transform: scale(1.05);
}
.drop-zone.active {
background-color: #f0f0f0;
border: 2px dashed #ccc;
}
配合 Vue 的 class 绑定:
<div
v-for="item in items"
:class="{ 'dragging': item.id === draggingId }"
draggable="true"
@dragstart="startDrag(item.id)"
>
{{ item.text }}
</div>
实现跨组件拖拽
通过 Vuex 或事件总线实现跨组件拖拽数据传递:
// 使用事件总线
const EventBus = new Vue()
// 拖拽源组件
EventBus.$emit('drag-start', payload)
// 放置目标组件
EventBus.$on('drag-start', payload => {
// 处理拖拽数据
})
移动端拖拽支持
对于移动端需要额外处理触摸事件:
<div
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
移动端可拖拽元素
</div>
methods: {
handleTouchStart(e) {
this.startX = e.touches[0].clientX
this.startY = e.touches[0].clientY
},
handleTouchMove(e) {
const deltaX = e.touches[0].clientX - this.startX
const deltaY = e.touches[0].clientY - this.startY
// 更新元素位置
}
}
性能优化建议
对于大量可拖拽元素,使用虚拟滚动技术减少 DOM 节点数量:

<draggable v-model="list">
<virtual-list :size="50" :remain="10">
<div v-for="item in list" :key="item.id">
{{ item.name }}
</div>
</virtual-list>
</draggable>






