vue实现拖拽放置
Vue 实现拖拽放置功能
使用 HTML5 原生拖放 API
HTML5 提供了原生的拖放 API,可以通过 draggable 属性、dragstart、dragover 和 drop 事件实现拖拽放置功能。
<template>
<div>
<div
v-for="item in items"
:key="item.id"
draggable="true"
@dragstart="handleDragStart($event, item)"
>
{{ item.name }}
</div>
<div
@dragover.prevent
@drop="handleDrop"
>
放置区域
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
],
draggedItem: null
}
},
methods: {
handleDragStart(event, item) {
this.draggedItem = item
event.dataTransfer.setData('text/plain', item.id)
},
handleDrop(event) {
event.preventDefault()
const itemId = event.dataTransfer.getData('text/plain')
console.log('Dropped item:', this.draggedItem)
}
}
}
</script>
使用第三方库 vue-draggable
对于更复杂的拖拽需求,可以使用第三方库如 vue-draggable(基于 Sortable.js)。
安装依赖:
npm install vuedraggable
使用示例:
<template>
<div>
<draggable
v-model="items"
group="items"
@end="onDragEnd"
>
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</draggable>
<draggable
v-model="anotherList"
group="items"
>
<div v-for="item in anotherList" :key="item.id">
{{ item.name }}
</div>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
],
anotherList: []
}
},
methods: {
onDragEnd() {
console.log('Drag ended', this.items)
}
}
}
</script>
自定义拖拽指令
对于需要完全自定义的拖拽行为,可以创建 Vue 自定义指令。
Vue.directive('drag', {
bind(el, binding) {
el.setAttribute('draggable', true)
el.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', binding.value)
el.style.opacity = '0.5'
})
el.addEventListener('dragend', () => {
el.style.opacity = '1'
})
}
})
使用示例:
<template>
<div>
<div v-drag="item.id" v-for="item in items" :key="item.id">
{{ item.name }}
</div>
<div
@dragover.prevent
@drop="handleDrop"
>
放置区域
</div>
</div>
</template>
拖拽放置的性能优化
对于大量元素的拖拽,建议使用虚拟滚动技术或限制拖拽元素的渲染数量。可以使用 vue-virtual-scroller 等库优化性能。
npm install vue-virtual-scroller
示例:

<template>
<RecycleScroller
class="scroller"
:items="items"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div
draggable="true"
@dragstart="handleDragStart($event, item)"
>
{{ item.name }}
</div>
</RecycleScroller>
</template>
以上方法可以根据具体需求选择使用,HTML5 原生 API 适合简单场景,vue-draggable 适合复杂交互,自定义指令提供最大灵活性。






