最近有个需求是从左边一个列表中,拖动列表元素到右边列表中,并且不是移动拖拽,而是复制拖拽,元素在右边列表中可以重复,比如左边是参加某个游戏的队员名单,右边是出场顺序,队员可以重复上场。类似这种效果:
代码:
// 左边的列表
<div class="left-list">
<p class="title">队员选择</p>
<draggable
class="dragArea"
:list="data.allPerson"
:group="{ name: 'person', pull: 'clone', put: false }"
item-key="id"
>
<template #item="{ element, index }">
<div class="left-person" >
<span class="item-name">{{ element.name }}</span>
</div>
</template>
</draggable>
</div>
// 右边的列表
<draggable
class="dragArea "
:list="data.allSelectedPerson"
group="person"
item-key="id"
>
<template #item="{ element, index }">
<div class="right-item">
<span>
{{ element.name }}
</span>
<span class="close-btn" @click="handleDeleteSelected(index)">
<icon-close /> </span
></div>
</template>
</draggable>
我用的是 Vue.Draggable 组件,不得不说这个组件真是太好用了,它的官方地址:vue.draggable github地址
官方演示地址: https://sortablejs.github.io/Vue.Draggable/#/clone 其中我用的就是 clone 模式。
Vue.Draggable 拿来即用,没啥难以上手的,就是我在使用的时候遇到一个问题,就是当右边有重复的数据时,多次上下快速拖动右边的元素排序,会偶发一个bug:右边列表会自动多出一个数据,并且操作不了(没法删除也没法给它排序)。
官方在 github 上的示例代码是:
<template>
<div class="row">
<div class="col-3">
<h3>Draggable 1</h3>
<draggable
class="dragArea list-group"
:list="list1"
:group="{ name: 'people', pull: 'clone', put: false }"
@change="log"
>
<div
class="list-group-item"
v-for="element in list1"
:key="element.name"
>
{{ element.name }}
</div>
</draggable>
</div>
<div class="col-3">
<h3>Draggable 2</h3>
<draggable
class="dragArea list-group"
:list="list2"
group="people"
@change="log"
>
<div
class="list-group-item"
v-for="element in list2"
:key="element.name"
>
{{ element.name }}
</div>
</draggable>
</div>
<rawDisplayer class="col-3" :value="list1" title="List 1" />
<rawDisplayer class="col-3" :value="list2" title="List 2" />
</div>
</template>
<script>
import draggable from "@/vuedraggable";
export default {
name: "clone",
display: "Clone",
order: 2,
components: {
draggable
},
data() {
return {
list1: [
{ name: "John", id: 1 },
{ name: "Joao", id: 2 },
{ name: "Jean", id: 3 },
{ name: "Gerard", id: 4 }
],
list2: [
{ name: "Juan", id: 5 },
{ name: "Edgard", id: 6 },
{ name: "Johnson", id: 7 }
]
};
},
methods: {
log: function(evt) {
window.console.log(evt);
}
}
};
</script>
<style scoped></style>
经过一番曲折的找bug原因历程,后来发现是我自己用的不合适,就是在右边表格的 item-key 属性用的是id,本以为id是唯一的,后来出现上面提到那个bug的时候,控制台也报警告说有重的 itemKey 。然后我意识到由于我右边的元素是可以重复的,所以其实用id做 itemKey 也不是唯一的。
后来我用 index 做右边拖拽列表的 itemKey 了,也不知道这样合不合适,但确实是没有刚才那个bug了,因为 index 是不会重复的。
// 右边的列表
<draggable
class="dragArea "
:list="data.allSelectedPerson"
group="person"
item-key="index"
>
<template #item="{ element, index }">
<div class="right-item">
<span>
{{ element.name }}
</span>
<span class="close-btn" @click="handleDeleteSelected(index)">
<icon-close /> </span
></div>
</template>
</draggable>
希望本文对您有所帮助,,也希望大佬不吝赐教!