Vuedraggable 如何在 2 个可拖动项之间交换项目
Vuedraggable how to swap item between 2 draggable
大家好,我在 vuedraggable 中遇到了问题。当我将“项目 2”拖到“项目 3”时 => 我希望“项目 3”与“项目 2”交换。
请帮助我。
假设您有多个列表并且每个列表都有自己的 <draggable>
元素,那么您需要为 <draggable>
元素分配一个新方法 handleMove(event)
。 event
参数很重要,因为 event.draggedContext
包含您要移动的项目的索引 (index
) 以及当前与您抓取的项目重叠的其他项目的索引(futureIndex
)。它还包含您从哪个列表中抓取的项目 (event.from
) 以及您希望将其放置在何处 (event.to
) 的信息。将这 4 个变量存储在某处,并在完成拖动时使用它们(函数 handleDragEnd()
)。
在 handleDragEnd()
中只需交换这 2 个项目,Vue 就会更新 HTML 模板。
<template>
<div class="row">
<div class="col-3">
<h3>My LEGO Bionicles</h3>
<draggable
class="list-group"
data-list="list1"
:list="list1"
group="bionicles"
@change="log"
itemKey="id"
:move="handleMoveItem"
@end="handleDragEndItem"
:options="{ animation: 500 }"
>
<template #item="{ element, index }">
<div class="list-group-item" :style="element.style">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="col-3">
<h3>Favourite LEGO Bionicle</h3>
<draggable
class="list-group"
data-list="list2"
:list="list2"
group="bionicles"
@change="log"
itemKey="id"
:move="handleMoveItem"
@end="handleDragEndItem"
:options="{ animation: 500 }"
>
<template #item="{ element, index }">
<div class="list-group-item" :style="element.style">
{{ element.name }}
</div>
</template>
</draggable>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable';
export default {
name: 'two-lists-swap',
display: 'Swapping between 2 lists',
order: 1,
components: {
draggable,
},
data() {
return {
list1: [
{ name: 'TOA Mata Nui', id: 1, style: { background: 'gold' } },
{
name: 'TOA Tahu',
id: 2,
style: { background: 'red', color: 'yellow' },
},
{ name: 'TOA Kopaka', id: 3, style: { background: 'white' } },
{
name: 'TOA Anakin',
id: 4,
style: { background: 'black', color: 'yellow' },
},
],
list2: [
{
name: 'TOA Gali',
id: 5,
style: { background: 'blue', color: 'yellow' },
},
{
name: 'TOA Lewa',
id: 6,
style: { background: 'green', color: 'yellow' },
},
{
name: 'TOA Pohatu',
id: 7,
style: { background: 'brown', color: 'white' },
},
],
};
},
methods: {
handleDragEndItem() {
if (this.originalList === this.futureList) {
this.movingItem = this[this.futureList][this.originalIndex];
this.futureItem = this[this.futureList][this.futureIndex];
if (this.movingItem && this.futureItem) {
let _list = Object.assign([], this[this.futureList]);
_list[this.futureIndex] = this.movingItem;
_list[this.originalIndex] = this.futureItem;
this[this.futureList] = _list;
}
} else {
this.movingItem = this[this.originalList][this.originalIndex];
this.futureItem = this[this.futureList][this.futureIndex];
if (this.movingItem && this.futureItem) {
let _listFrom = Object.assign([], this[this.originalList]);
let _listTo = Object.assign([], this[this.futureList]);
_listTo[this.futureIndex] = this.movingItem;
_listFrom[this.originalIndex] = this.futureItem;
this[this.originalList] = _listFrom;
this[this.futureList] = _listTo;
}
}
document
.querySelectorAll('.list-group-item')
.forEach((el) => (el.style.border = 'none'));
this.$toast.show('dragEnd');
},
handleMoveItem(event) {
document
.querySelectorAll('.list-group-item')
.forEach((el) => (el.style.border = 'none'));
const { index, futureIndex } = event.draggedContext;
this.originalIndex = index;
this.futureIndex = futureIndex;
this.originalList = event.from.getAttribute('data-list');
this.futureList = event.to.getAttribute('data-list');
if (this[this.futureList][this.futureIndex]) {
event.to.children[this.futureIndex].style.border = '2px solid orange';
}
return false; // disable sort
},
},
};
</script>
<style>
.list-group-item {
padding: 5px 10px;
cursor: grab;
}
</style>
大家好,我在 vuedraggable 中遇到了问题。当我将“项目 2”拖到“项目 3”时 => 我希望“项目 3”与“项目 2”交换。 请帮助我。
假设您有多个列表并且每个列表都有自己的 <draggable>
元素,那么您需要为 <draggable>
元素分配一个新方法 handleMove(event)
。 event
参数很重要,因为 event.draggedContext
包含您要移动的项目的索引 (index
) 以及当前与您抓取的项目重叠的其他项目的索引(futureIndex
)。它还包含您从哪个列表中抓取的项目 (event.from
) 以及您希望将其放置在何处 (event.to
) 的信息。将这 4 个变量存储在某处,并在完成拖动时使用它们(函数 handleDragEnd()
)。
在 handleDragEnd()
中只需交换这 2 个项目,Vue 就会更新 HTML 模板。
<template>
<div class="row">
<div class="col-3">
<h3>My LEGO Bionicles</h3>
<draggable
class="list-group"
data-list="list1"
:list="list1"
group="bionicles"
@change="log"
itemKey="id"
:move="handleMoveItem"
@end="handleDragEndItem"
:options="{ animation: 500 }"
>
<template #item="{ element, index }">
<div class="list-group-item" :style="element.style">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="col-3">
<h3>Favourite LEGO Bionicle</h3>
<draggable
class="list-group"
data-list="list2"
:list="list2"
group="bionicles"
@change="log"
itemKey="id"
:move="handleMoveItem"
@end="handleDragEndItem"
:options="{ animation: 500 }"
>
<template #item="{ element, index }">
<div class="list-group-item" :style="element.style">
{{ element.name }}
</div>
</template>
</draggable>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable';
export default {
name: 'two-lists-swap',
display: 'Swapping between 2 lists',
order: 1,
components: {
draggable,
},
data() {
return {
list1: [
{ name: 'TOA Mata Nui', id: 1, style: { background: 'gold' } },
{
name: 'TOA Tahu',
id: 2,
style: { background: 'red', color: 'yellow' },
},
{ name: 'TOA Kopaka', id: 3, style: { background: 'white' } },
{
name: 'TOA Anakin',
id: 4,
style: { background: 'black', color: 'yellow' },
},
],
list2: [
{
name: 'TOA Gali',
id: 5,
style: { background: 'blue', color: 'yellow' },
},
{
name: 'TOA Lewa',
id: 6,
style: { background: 'green', color: 'yellow' },
},
{
name: 'TOA Pohatu',
id: 7,
style: { background: 'brown', color: 'white' },
},
],
};
},
methods: {
handleDragEndItem() {
if (this.originalList === this.futureList) {
this.movingItem = this[this.futureList][this.originalIndex];
this.futureItem = this[this.futureList][this.futureIndex];
if (this.movingItem && this.futureItem) {
let _list = Object.assign([], this[this.futureList]);
_list[this.futureIndex] = this.movingItem;
_list[this.originalIndex] = this.futureItem;
this[this.futureList] = _list;
}
} else {
this.movingItem = this[this.originalList][this.originalIndex];
this.futureItem = this[this.futureList][this.futureIndex];
if (this.movingItem && this.futureItem) {
let _listFrom = Object.assign([], this[this.originalList]);
let _listTo = Object.assign([], this[this.futureList]);
_listTo[this.futureIndex] = this.movingItem;
_listFrom[this.originalIndex] = this.futureItem;
this[this.originalList] = _listFrom;
this[this.futureList] = _listTo;
}
}
document
.querySelectorAll('.list-group-item')
.forEach((el) => (el.style.border = 'none'));
this.$toast.show('dragEnd');
},
handleMoveItem(event) {
document
.querySelectorAll('.list-group-item')
.forEach((el) => (el.style.border = 'none'));
const { index, futureIndex } = event.draggedContext;
this.originalIndex = index;
this.futureIndex = futureIndex;
this.originalList = event.from.getAttribute('data-list');
this.futureList = event.to.getAttribute('data-list');
if (this[this.futureList][this.futureIndex]) {
event.to.children[this.futureIndex].style.border = '2px solid orange';
}
return false; // disable sort
},
},
};
</script>
<style>
.list-group-item {
padding: 5px 10px;
cursor: grab;
}
</style>