vue 原生实现拖拽
Vue 原生实现拖拽功能
在 Vue 中实现拖拽功能可以通过原生 HTML5 的拖拽 API 结合 Vue 的事件绑定来完成。以下是具体实现方法:
基础拖拽实现
HTML 结构
<template>
<div
class="draggable-item"
draggable="true"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
>
拖拽元素
</div>
<div
class="drop-zone"
@dragover.prevent
@dragenter.prevent
@drop="handleDrop"
>
放置区域
</div>
</template>
JavaScript 逻辑
<script>
export default {
methods: {
handleDragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id)
e.target.classList.add('dragging')
},
handleDragEnd(e) {
e.target.classList.remove('dragging')
},
handleDrop(e) {
const id = e.dataTransfer.getData('text/plain')
const draggableElement = document.getElementById(id)
e.target.appendChild(draggableElement)
}
}
}
</script>
CSS 样式
.draggable-item {
width: 100px;
height: 100px;
background: #42b983;
cursor: move;
}
.drop-zone {
width: 300px;
height: 300px;
border: 2px dashed #ccc;
}
.dragging {
opacity: 0.5;
}
列表排序拖拽
对于列表项的拖拽排序,可以结合 v-for 和数组操作:
模板部分
<template>
<ul>
<li
v-for="(item, index) in list"
:key="item.id"
draggable="true"
@dragstart="handleDragStart($event, index)"
@dragover.prevent
@dragenter="handleDragEnter($event, index)"
@drop="handleDrop($event, index)"
>
{{ item.text }}
</li>
</ul>
</template>
脚本部分
<script>
export default {
data() {
return {
list: [
{ id: 1, text: '项目1' },
{ id: 2, text: '项目2' },
{ id: 3, text: '项目3' }
],
draggedIndex: null
}
},
methods: {
handleDragStart(e, index) {
this.draggedIndex = index
e.dataTransfer.effectAllowed = 'move'
},
handleDragEnter(e, index) {
e.dataTransfer.dropEffect = 'move'
},
handleDrop(e, dropIndex) {
if (this.draggedIndex !== null) {
const item = this.list.splice(this.draggedIndex, 1)[0]
this.list.splice(dropIndex, 0, item)
this.draggedIndex = null
}
}
}
}
</script>
跨组件拖拽
对于跨组件拖拽,可以使用 Vue 的 provide/inject 或全局状态管理:
父组件
provide() {
return {
dragState: reactive({
draggedItem: null,
dropTarget: null
})
}
}
子组件

inject: ['dragState'],
methods: {
startDrag(item) {
this.dragState.draggedItem = item
},
handleDrop() {
if (this.dragState.draggedItem) {
// 处理拖拽逻辑
}
}
}
性能优化建议
- 使用
requestAnimationFrame优化拖拽动画 - 对于大型列表,使用虚拟滚动技术
- 减少拖拽过程中的 DOM 操作
- 使用 CSS
transform代替top/left定位
以上方法提供了 Vue 中原生实现拖拽功能的不同场景解决方案,可以根据具体需求选择适合的方式。






