vue实现左右拖拽
实现左右拖拽的基本思路
在Vue中实现左右拖拽功能,通常需要结合HTML5的拖拽API或第三方库。核心逻辑包括监听拖拽事件、更新数据状态以及动态调整DOM元素位置。
使用HTML5原生拖拽API
通过HTML5的draggable属性和相关事件实现基础拖拽功能。
<template>
<div class="container">
<div
class="draggable-item"
v-for="(item, index) in items"
:key="index"
draggable="true"
@dragstart="handleDragStart(index)"
@dragover.prevent
@drop="handleDrop(index)"
>
{{ item }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: ['Item 1', 'Item 2', 'Item 3', 'Item 4'],
draggedIndex: null
}
},
methods: {
handleDragStart(index) {
this.draggedIndex = index
},
handleDrop(index) {
if (this.draggedIndex !== null) {
const item = this.items.splice(this.draggedIndex, 1)[0]
this.items.splice(index, 0, item)
this.draggedIndex = null
}
}
}
}
</script>
<style>
.container {
display: flex;
gap: 10px;
}
.draggable-item {
padding: 10px;
background: #eee;
border: 1px solid #ccc;
cursor: move;
}
</style>
使用第三方库Vue.Draggable
对于更复杂的拖拽需求,推荐使用vue.draggable库,它基于Sortable.js封装,提供更丰富的功能。
安装依赖:
npm install vuedraggable
示例代码:
<template>
<draggable
v-model="items"
tag="div"
class="container"
@start="dragStart"
@end="dragEnd"
>
<div v-for="(item, index) in items" :key="index" class="draggable-item">
{{ item }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
items: ['Item 1', 'Item 2', 'Item 3', 'Item 4']
}
},
methods: {
dragStart() {
console.log('Drag started')
},
dragEnd() {
console.log('Drag ended')
}
}
}
</script>
<style>
.container {
display: flex;
gap: 10px;
}
.draggable-item {
padding: 10px;
background: #eee;
border: 1px solid #ccc;
}
</style>
实现拖拽边界限制
若需要限制拖拽范围(如仅允许水平拖拽),可通过CSS或事件控制。
CSS限制:
.container {
overflow-x: auto;
white-space: nowrap;
}
.draggable-item {
display: inline-block;
}
事件控制(原生API):
handleDragOver(e) {
e.preventDefault()
const rect = e.currentTarget.getBoundingClientRect()
const x = e.clientX - rect.left
if (x > rect.width || x < 0) {
return false
}
}
性能优化建议
对于大量可拖拽元素,建议使用虚拟滚动或按需渲染。vue.draggable支持结合vue-virtual-scroller等库优化性能。
<draggable v-model="items" :options="{ animation: 150 }">
<!-- 结合虚拟滚动 -->
</draggable>






