vue 实现卡片拖拽
Vue 实现卡片拖拽
使用 HTML5 拖拽 API
HTML5 提供了原生的拖拽 API,可以通过 draggable 属性实现拖拽功能。在 Vue 中,可以通过事件绑定来实现拖拽逻辑。
<template>
<div class="card" draggable="true"
@dragstart="handleDragStart"
@dragend="handleDragEnd">
卡片内容
</div>
</template>
<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');
}
}
};
</script>
<style>
.card {
width: 100px;
height: 100px;
background: #eee;
margin: 10px;
cursor: move;
}
.dragging {
opacity: 0.5;
}
</style>
使用 Vue.Draggable 库
Vue.Draggable 是一个基于 Sortable.js 的 Vue 拖拽组件库,提供了更高级的拖拽功能,如列表排序、跨列表拖拽等。
安装 Vue.Draggable:

npm install vuedraggable
示例代码:
<template>
<draggable v-model="cards" group="cards" @end="onDragEnd">
<div v-for="card in cards" :key="card.id" class="card">
{{ card.content }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable';
export default {
components: { draggable },
data() {
return {
cards: [
{ id: 1, content: '卡片1' },
{ id: 2, content: '卡片2' },
{ id: 3, content: '卡片3' }
]
};
},
methods: {
onDragEnd() {
console.log('拖拽完成');
}
}
};
</script>
<style>
.card {
width: 100px;
height: 100px;
background: #eee;
margin: 10px;
cursor: move;
}
</style>
自定义拖拽逻辑
如果需要更灵活的拖拽逻辑,可以通过监听鼠标事件(mousedown、mousemove、mouseup)来实现。

<template>
<div class="card"
@mousedown="startDrag"
:style="{ left: cardLeft + 'px', top: cardTop + 'px' }">
卡片内容
</div>
</template>
<script>
export default {
data() {
return {
cardLeft: 0,
cardTop: 0,
isDragging: false,
startX: 0,
startY: 0
};
},
methods: {
startDrag(e) {
this.isDragging = true;
this.startX = e.clientX - this.cardLeft;
this.startY = e.clientY - this.cardTop;
document.addEventListener('mousemove', this.onDrag);
document.addEventListener('mouseup', this.stopDrag);
},
onDrag(e) {
if (this.isDragging) {
this.cardLeft = e.clientX - this.startX;
this.cardTop = e.clientY - this.startY;
}
},
stopDrag() {
this.isDragging = false;
document.removeEventListener('mousemove', this.onDrag);
document.removeEventListener('mouseup', this.stopDrag);
}
}
};
</script>
<style>
.card {
width: 100px;
height: 100px;
background: #eee;
position: absolute;
cursor: move;
}
</style>
拖拽边界限制
为了防止卡片拖拽超出容器范围,可以在拖拽逻辑中添加边界检查。
onDrag(e) {
if (this.isDragging) {
const newLeft = e.clientX - this.startX;
const newTop = e.clientY - this.startY;
const containerWidth = this.$el.parentNode.clientWidth;
const containerHeight = this.$el.parentNode.clientHeight;
const cardWidth = this.$el.clientWidth;
const cardHeight = this.$el.clientHeight;
this.cardLeft = Math.max(0, Math.min(newLeft, containerWidth - cardWidth));
this.cardTop = Math.max(0, Math.min(newTop, containerHeight - cardHeight));
}
}
拖拽动画优化
通过 CSS 过渡效果可以让拖拽更加平滑。
.card {
transition: transform 0.1s ease;
}
.dragging {
transform: scale(1.05);
}
以上方法可以根据实际需求选择使用,HTML5 拖拽 API 适合简单场景,Vue.Draggable 适合列表排序,自定义拖拽逻辑适合复杂交互。






