【Laravel / Vue】ドラッグ&ドロップでならびかえ

インストール

npm i vuedraggable
yarn add vuedraggable

使う

  • components/Items.vue
<template> 
  <draggable v-model="items" :options="options">
    <div v-for="(item, index) in items" :key="index">
      {{ item }}
    </div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'

export default {
  components: { draggable },
   data () {
    return {
      items: [],
      options: {
        animation: 200
      },
    }
  },
  props: ['propItems'],
  mounted () {
    this.items = this.propItems
  },
}
</script>

アイコンでハンドルする場合

  • draggableコンポーネントのhandleで対象のアイコンのクラス名を指定してあげるだけ
<template> 
  <draggable v-model="items" :options="options" handle=".handle">
    <div v-for="(item, index) in items" :key="index">
      <i class="fas fa-ellipsis-v handle"></i>
      {{ item }}
    </div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'

export default {
  components: { draggable },
   data () {
    return {
      items: [],
      options: {
        animation: 200
      },
    }
  },
  props: ['propItems'],
  mounted () {
    this.items = this.propItems
  },
}
</script>

順番を更新する

例えば、テーブルの各レコードにsortカラムを持っていてそれを更新したいとする

並べ替え後、「更新」ボタンなどで一括更新する場合

draggableによって配列の順番は既に更新されているので、
その配列のindexでsortを更新するだけでOK

アイテムが並べ替えられたタイミングで即時更新する場合

draggableが用意してくれている@endイベントを活用する

<template> 
  <!-- ⭐️ @endを追加 -->
  <draggable v-model="items" :options="options" handle=".handle" @end="onSort">
    <div v-for="(item, index) in items" :key="index">
      <i class="fas fa-ellipsis-v handle"></i>
      {{ item }}
    </div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'

export default {
  components: { draggable },
   data () {
    return {
      items: [],
      options: {
        animation: 200
      },
    }
  },
  props: ['propItems'],
  mounted () {
    this.items = this.propItems
  },
  // ⭐️ ソート完了後に実行するメソッド追加
  methods: {
    onSort (event) {
      // ⭐️ 新しいthis.itemsの更新処理
    },
  },
}
</script>

補足

@endから渡されたevent変数の内容をコンソールログでみてみると、
下記のように移動先index (newIndex)と移動元index (oldIndex)が入ってる

これをもとに条件判定とかもできそう