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 模板。

LIVE DEMO HERE

<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>