组件 - vue.draggable.next
安装
yarn add vuedraggable@next
npm i -S vuedraggable@next
使用链接
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.min.js"></script>
<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
<script src="//cdn.jsdelivr.net/npm/sortablejs@1.10.2/Sortable.min.js"></script>
<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/4.0.0/vuedraggable.umd.min.js"></script>
使用例子
<draggable
v-model="myArray"
group="people"
@start="drag=true"
@end="drag=false"
item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
</draggable>
import draggable from 'vuedraggable'
export default {
components: {
draggable,
},
data() {
return {
drag: false,
myArray: [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Doe' }
]
}
}
}
配置
- sort: 是否可排序(决定是否拖拽排序动作执行成功)
- group: 拖拽组,用于多列表之间的拖拽
- animation: 动画时间(毫秒)
- disabled: 是否禁用拖拽
- ghostClass: 拖拽时的占位符类名
- chosenClass: 选中项的类名
- dragClass: 拖动中的类名
组动画
<draggable v-model="myArray" tag="transition-group" item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
</draggable>
使用插槽
Footer 插槽
<draggable v-model="myArray" item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
<template #footer>
<button @click="addPeople">Add</button>
</template>
</draggable>
Header 插槽
<draggable v-model="myArray" item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
<template #header>
<button @click="addPeople">Add</button>
</template>
</draggable>
迁移
Vue 2 版本
<draggable v-model="myArray">
<div v-for="element in myArray" :key="element.id">{{element.name}}</div>
</draggable>
Vue 3 版本
<draggable v-model="myArray" item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
</draggable>
可能遇见的错误
1. Error: Item slot must have only one child
问题表现
代码:
<draggable
v-model="formData.contacts"
@start="drag = true"
@end="drag = false"
item-key="index"
>
<template #item="{ element, index }">
<!-- {{ element.name }} -->
<div class="connects">
<!-- {{ element.name }} -->
<el-input
v-model="element.name"
@input="inputContacts(index)"
placeholder="名字"
></el-input>
<el-input
v-model="element.phone"
@input="inputContacts(index)"
placeholder="联系方式"
></el-input>
</div>
</template>
</draggable>
解决办法
删除中间注释。确保 #item
插槽只有一个根元素。
<draggable
v-model="formData.contacts"
@start="drag = true"
@end="drag = false"
item-key="index"
>
<template #item="{ element, index }">
<div class="connects">
<el-input
v-model="element.name"
@input="inputContacts(index)"
placeholder="名字"
></el-input>
<el-input
v-model="element.phone"
@input="inputContacts(index)"
placeholder="联系方式"
></el-input>
</div>
</template>
</draggable>
其他配置选项
- filter: 排除某些元素不参与拖拽
- preventOnFilter: 当过滤器匹配时是否阻止默认行为
- draggable: 指定哪些元素可以拖拽
- ignore: 忽略某些元素不参与拖拽
- pull: 控制元素是否可以从一个列表中拉出
- put: 控制元素是否可以放入一个列表
- swapThreshold: 交换阈值(0-1 之间)
- invertSwap: 是否反转交换逻辑
示例:多列表拖拽
<template>
<div>
<draggable v-model="list1" group="people" @start="drag = true" @end="drag = false" item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
</draggable>
<draggable v-model="list2" group="people" @start="drag = true" @end="drag = false" item-key="id">
<template #item="{element}">
<div>{{element.name}}</div>
</template>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: {
draggable,
},
data() {
return {
drag: false,
list1: [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
],
list2: [
{ id: 3, name: 'Doe' },
{ id: 4, name: 'Smith' }
]
}
}
}
</script>