複数の配列を用意してvuedraggableを使用する方法


vuedraggableを使用した開発で、躓いた話です。
わかってしまえば簡単なことで、記事にするほどのことかと思いましたが、自分が躓いたと言うことは、もしかしたら誰か躓くことがあるかもしれないと思い、記事にすることにしました。

躓いたこと

ある配列の要素を、変数の数だけ空の配列を用意し、ドラッグ&ドロップできるようにしたかった。
検索して出てくるサイトではitem1,item2などdataに配列を定義した状態の記事は見つけられたが、どう定義していいかわからなかった。

index.vue
<template>
  <v-row>
    <v-col>
      <v-list>
        <v-list-item-title> アンパンヘッドボーイ </v-list-item-title>
        <draggable v-model="item1" group="item">
          <v-list-item v-for="item in item1" :key="item.id">
            {{ item.name }}
          </v-list-item>
        </draggable>
      </v-list>
    </v-col>
    <v-col>
      <v-list>
        <v-list-item-title> カバ </v-list-item-title>
        <draggable v-model="item2" group="item">
          <v-list-item v-for="item in item2" :key="item.id">
            {{ item.name }}
          </v-list-item>
        </draggable>
      </v-list>
    </v-col>
    <v-col>
      <v-list>
        <v-list-item-title> うさぎ </v-list-item-title>
        <draggable v-model="item3" group="item">
          <v-list-item v-for="item in item3" :key="item.id">
            {{ item.name }}
          </v-list-item>
        </draggable>
      </v-list>
    </v-col>
  </v-row>
</template>

<script>
import draggable from "vuedraggable";

export default {
  components: { draggable },
  data: () => ({
    item1: [
      { id: 1, name: "アンパン1" },
      { id: 2, name: "アンパン2" },
      { id: 3, name: "アンパン3" },
    ],
    item2: [],
    item3: [],
  }),
};
</script>


今の状態

このアンパンを配る相手の分だけitemを定義しないといけない。
後々配る相手を動的に削除、追加を管理できるようにしたいと思いました。

方法

動物たちのデータをstoreで管理します。
そして動物の数(state.animals.length)だけ空の配列を用意してあげます。

index.js
export const state = () => ({
  animals: [
    { id: 1, name: "カバ" },
    { id: 2, name: "うさぎ" },
    { id: 3, name: "犬" },
  ],
  items: [],
});
// ------------------Mutations-------------------------------
export const mutations = {
  items(state) {
    const newItems = new Array();
    for (let i = 0; i < state.animals.length; i++) {
      newItems[i] = new Array();
    }
    state.items = newItems;
  },

その後、vueファイルの動物の部分を

index.vue
<v-row>
    <v-col v-for="(animal, index) in animals" :key="index">
      <v-list>
        <v-list-item-title> {{ animal.name }} </v-list-item-title>
        <draggable v-model="items[index]" group="item">
          <v-list-item v-for="item in items[index]" :key="item.id">
            {{ item.name }}
          </v-list-item>
        </draggable>
      </v-list>
    </v-col>
  </v-row>

<script>
//追加
created() {
    this.$store.commit("items");
  },
computed: {
    items() {
      return this.$store.state.items;
    },
</script>

と書き換えてあげれば、完成です!

っと言いたいところなのですが、このままでは操作した瞬間に

vuex do not mutate vuex store outside mutation handlers

とエラーが出てしまいます。
このvuedraggableを導入するにあたり、何度も苦しめられてきたエラーです。

ただ今回はあくまで配列を用意する記事ですので、
vuedraggableで連想配列を操作した時に[vuex do not mutate vuex store outside mutation handlers]となった時の話の記事で紹介しています。

おわり

不備、不明点があれば、お手数ですがコメントにてお伝え下さい。