vue实现组件拖动
Vue 实现组件拖动的几种方法
使用 HTML5 拖放 API
HTML5 原生提供了拖放 API,可以通过 draggable 属性实现基础拖拽功能。在 Vue 中可以通过事件绑定实现交互逻辑。
<template>
<div
draggable="true"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
@dragover.prevent
@drop="handleDrop"
>
可拖拽元素
</div>
</template>
<script>
export default {
methods: {
handleDragStart(e) {
e.dataTransfer.setData('text/plain', 'drag-data');
},
handleDrop(e) {
const data = e.dataTransfer.getData('text/plain');
// 处理放置逻辑
}
}
}
</script>
使用第三方库 vue-draggable
vue-draggable 是基于 Sortable.js 的 Vue 拖拽组件,适合列表排序场景。
安装:
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() {
// 拖拽结束处理
}
}
}
</script>
使用 interact.js 实现高级拖拽
interact.js 提供了更强大的拖拽功能,支持限制范围、惯性等高级特性。
安装:
npm install interactjs
使用示例:

<template>
<div ref="draggable" class="draggable-element">
可拖拽元素
</div>
</template>
<script>
import interact from 'interactjs';
export default {
mounted() {
interact(this.$refs.draggable)
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
onmove: this.dragMoveListener
});
},
methods: {
dragMoveListener(event) {
const target = event.target;
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.transform = `translate(${x}px, ${y}px)`;
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
}
}
</script>
<style>
.draggable-element {
touch-action: none;
user-select: none;
}
</style>
使用 Vue 自定义指令实现拖拽
可以通过 Vue 自定义指令封装拖拽逻辑,提高代码复用性。
Vue.directive('drag', {
bind(el, binding) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
el.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
el.style.top = (el.offsetTop - pos2) + "px";
el.style.left = (el.offsetLeft - pos1) + "px";
}
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
}
});
使用方式:
<div v-drag class="draggable-box"></div>
移动端触摸事件支持
对于移动端设备,需要使用触摸事件替代鼠标事件:
el.addEventListener('touchstart', handleTouchStart, { passive: false });
el.addEventListener('touchmove', handleTouchMove, { passive: false });
function handleTouchStart(e) {
e.preventDefault();
const touch = e.touches[0];
// 记录初始位置
}
function handleTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
// 计算移动距离并更新元素位置
}
以上方法可根据具体需求选择,简单场景可使用 HTML5 API 或 vue-draggable,复杂交互推荐使用 interact.js 或自定义指令实现。






