1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

vuedraggableで連想配列を操作した時に[vuex do not mutate vuex store outside mutation handlers]となった時の話

Posted at

はじめに

本記事は複数の配列を用意してvuedraggableを使用する方法の続きとなっています。

また、今回紹介する方法は1つの方法であって、正しい方法があると思います。
その事を念頭に置いて温かい目で見ていただけると助かります。
また、正しい方法をご存知の方がいましたら、ご教授いただけると幸いです。

前回までのあらすじ

アンパンヘッドボーイはアンパンを配る動物の数だけ袋(空の配列)を用意して欲しかった。
そこで、工場(store)であらかじめ動物の数を把握することにしました。
見事成功してアンパンを配ろうとしたその時、奴が現れこう言いました。

vuex do not mutate vuex store outside mutation handlers

茶番おわり

本題

この原因となっているのが、

computed: {
    items() {
      return this.$store.state.items;
    },
  },

これです。
これを下記のように書き直しても

computed: {
    animals: {
     get(){
      return this.$store.state.items
      }
     set(value){
      this.$store.commit("hoge",value)
      }
    },
  },

としてもエラーが出ます。

原因

上記の渡し方だと参照渡しになってしまうみたいです。
そのために色々な方法を試してみたのですがうまくいかず、試行錯誤の末たどり着いたのがこの方法でした。

対策

data: () => ({
    items: [],
  }),

  created() {
    const items = this.$store.state.items;
    items.forEach((item) => this.items.push(item));
  },

dataでitemsを定義して、createdの段階で新しい配列として定義し直してあげました。

スクリーンショット 2021-12-05 13.15.52.png

おわり

無事皆にアンパンを配ることができました。
方法は間違っているかもしれませんが、とりあえず動かしたい方は試してみてください。

また、他に方法をご存知の方がいましたら、ご指導のほどよろしくお願いします。

コード

*コンポーネント化しているので、前の記事と多少コードが変わっています。

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>
    <animals />
  </v-row>
</template>

<script>
import draggable from "vuedraggable";
import animals from "~/components/animals.vue";

export default {
  components: { draggable, animals },

  data: () => ({
    item1: [
      { id: 1, name: "アンパン1" },
      { id: 2, name: "アンパン2" },
      { id: 3, name: "アンパン3" },
    ],
  }),
};
</script>
animals.vue
<template>
  <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>
</template>

<script>
import draggable from "vuedraggable";

export default {
  components: { draggable },
  data: () => ({
    items: [],
  }),

  created() {
    this.$store.commit("items");

    const items = this.$store.state.items;
    items.forEach((item) => this.items.push(item));
  },

  computed: {
    animals() {
      return this.$store.state.animals;
    },
  },
};
</script>

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;
  },
};
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?