vue 实现拖拽插件
Vue 拖拽插件实现方法
使用原生 HTML5 拖拽 API
HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。在 Vue 中可以直接使用这些 API。
<template>
<div
draggable="true"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
@dragover="handleDragOver"
@drop="handleDrop"
>
拖拽元素
</div>
</template>
<script>
export default {
methods: {
handleDragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id)
},
handleDragOver(e) {
e.preventDefault()
},
handleDrop(e) {
e.preventDefault()
const data = e.dataTransfer.getData('text/plain')
const draggableElement = document.getElementById(data)
e.target.appendChild(draggableElement)
}
}
}
</script>
使用第三方库 Vue.Draggable
Vue.Draggable 是一个基于 Sortable.js 的 Vue 拖拽组件,提供了更高级的功能和更好的兼容性。
安装:
npm install vuedraggable
基本用法:
<template>
<draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false">
<div v-for="element in myArray" :key="element.id">
{{ element.name }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: {
draggable
},
data() {
return {
myArray: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
]
}
}
}
</script>
自定义拖拽指令
可以创建自定义指令来实现更灵活的拖拽功能。
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.4'
})
el.addEventListener('dragend', () => {
el.style.opacity = '1'
})
}
})
使用指令:
<div v-drag="item.id" v-for="item in items" :key="item.id">
{{ item.name }}
</div>
拖拽排序实现
结合 Vue 的响应式特性,可以实现列表的拖拽排序。
<template>
<ul>
<li
v-for="(item, index) in list"
:key="item.id"
draggable="true"
@dragstart="dragStart(index)"
@dragover.prevent="dragOver(index)"
@drop="drop(index)"
>
{{ item.text }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
],
draggedIndex: null
}
},
methods: {
dragStart(index) {
this.draggedIndex = index
},
dragOver(index) {
if (this.draggedIndex !== index) {
const draggedItem = this.list[this.draggedIndex]
this.list.splice(this.draggedIndex, 1)
this.list.splice(index, 0, draggedItem)
this.draggedIndex = index
}
},
drop() {
this.draggedIndex = null
}
}
}
</script>
跨组件拖拽实现
使用事件总线或 Vuex 可以实现跨组件的拖拽功能。
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
拖出组件:
<template>
<div
draggable="true"
@dragstart="dragStart"
>
拖拽我
</div>
</template>
<script>
import { EventBus } from './event-bus'
export default {
methods: {
dragStart(e) {
EventBus.$emit('drag-start', { data: this.itemData })
}
}
}
</script>
放入组件:
<template>
<div
@dragover.prevent
@drop="handleDrop"
>
放入区域
</div>
</template>
<script>
import { EventBus } from './event-bus'
export default {
created() {
EventBus.$on('drag-start', (data) => {
this.draggedData = data
})
},
methods: {
handleDrop() {
if (this.draggedData) {
// 处理放入逻辑
}
}
}
}
</script>
以上方法提供了从简单到复杂的多种拖拽实现方案,可以根据项目需求选择合适的实现方式。对于大多数应用场景,推荐使用 Vue.Draggable 组件,它提供了丰富的功能和良好的兼容性。







