vue实现卡片拖拽
Vue 实现卡片拖拽的方法
使用 HTML5 拖放 API
HTML5 提供了原生拖放 API,结合 Vue 可以轻松实现拖拽功能。以下是一个基本实现示例:
<template>
<div
class="card"
draggable="true"
@dragstart="handleDragStart"
@dragover.prevent
@drop="handleDrop"
>
{{ cardContent }}
</div>
</template>
<script>
export default {
data() {
return {
cardContent: '可拖拽卡片'
}
},
methods: {
handleDragStart(e) {
e.dataTransfer.setData('text/plain', this.cardContent)
},
handleDrop(e) {
e.preventDefault()
const data = e.dataTransfer.getData('text/plain')
this.cardContent = data
}
}
}
</script>
使用 Vue.Draggable 库
Vue.Draggable 是基于 Sortable.js 的 Vue 组件,提供了更丰富的拖拽功能。
安装依赖:
npm install vuedraggable
基本用法:
<template>
<draggable
v-model="cards"
group="cards"
@start="drag=true"
@end="drag=false"
>
<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' }
]
}
}
}
</script>
自定义拖拽实现
对于更复杂的拖拽需求,可以结合鼠标事件实现自定义拖拽逻辑:
<template>
<div class="card-container">
<div
v-for="card in cards"
:key="card.id"
class="card"
:style="{ left: card.x + 'px', top: card.y + 'px' }"
@mousedown="startDrag(card, $event)"
>
{{ card.content }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
cards: [
{ id: 1, content: '卡片1', x: 0, y: 0 },
{ id: 2, content: '卡片2', x: 100, y: 100 }
],
dragging: null,
offsetX: 0,
offsetY: 0
}
},
methods: {
startDrag(card, e) {
this.dragging = card
this.offsetX = e.clientX - card.x
this.offsetY = e.clientY - card.y
document.addEventListener('mousemove', this.onDrag)
document.addEventListener('mouseup', this.stopDrag)
},
onDrag(e) {
if (this.dragging) {
this.dragging.x = e.clientX - this.offsetX
this.dragging.y = e.clientY - this.offsetY
}
},
stopDrag() {
this.dragging = null
document.removeEventListener('mousemove', this.onDrag)
document.removeEventListener('mouseup', this.stopDrag)
}
}
}
</script>
<style>
.card-container {
position: relative;
height: 500px;
}
.card {
position: absolute;
width: 200px;
height: 100px;
background: #fff;
border: 1px solid #ddd;
cursor: move;
}
</style>
拖拽排序实现
实现卡片在容器内的拖拽排序:
<template>
<div class="card-list">
<div
v-for="(card, index) in cards"
:key="card.id"
class="card"
draggable="true"
@dragstart="dragStart(index)"
@dragover.prevent="dragOver(index)"
@drop="drop(index)"
>
{{ card.content }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
cards: [
{ id: 1, content: '卡片1' },
{ id: 2, content: '卡片2' },
{ id: 3, content: '卡片3' }
],
draggedIndex: null
}
},
methods: {
dragStart(index) {
this.draggedIndex = index
},
dragOver(index) {
if (this.draggedIndex !== index) {
const draggedItem = this.cards[this.draggedIndex]
this.cards.splice(this.draggedIndex, 1)
this.cards.splice(index, 0, draggedItem)
this.draggedIndex = index
}
},
drop() {
this.draggedIndex = null
}
}
}
</script>
以上方法提供了不同复杂度的实现方案,可以根据项目需求选择合适的方案。HTML5 拖放 API 适合简单场景,Vue.Draggable 适合列表排序,自定义实现则提供了最大的灵活性。






