PR

Vuexで、複製したオブジェクトを配列に詰め込んで、それぞれのオブジェクトを変更しようとしてハマった話

Javascript
記事内に広告が含まれています。
スポンサーリンク

Vue.jsでちょこっとプログラムを書いていてハマったので備忘として記事にします。

スポンサーリンク

やりたかったこと

複製したオブジェクトを配列に詰め込んで、後からそれぞれのオブジェクトを変更したかったのです。

例えば、配列orderにオブジェクトorderDetailsを複数追加してしまうと、追加したうち1つを更新すると、追加したすべてのorderDetailsが同じように更新されてしまいます。

import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 3,
    order: [],
    outletDetails: {
      id: null,
      device: 'iPad'
    }
  },
  getters: {
  },
  mutations: {
    generate(state){
      for (let index = 0; index < state.count; index++) {
        state.order.push(state.outletDetails)
      }
    }
  },
  actions: {
    generate({ commit }) {
      commit('generate')
    }
  },
  modules: {
  }
})

上記の例で言うと、アクションgenerateを実行すると、outletDetailsを複製して3つ追加したつもりでしたが、実際にはoutletDetailsを参照するエイリアスのようなものを3つ作ってしまったのでした。

解決策

一度JSONにしたオブジェクトoutletDetailsを、JSONにパースして追加していったら、それぞれ独立したオブジェクトになった。

import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 3,
    order: [],
    outletDetails: {
      id: null,
      device: 'iPad'
    }
  },
  getters: {
  },
  mutations: {
    generate(state){
      for (let index = 0; index < state.count; index++) {

        state.order.push(JSON.parse(JSON.stringify(state.outletDetails)))
      }
    }
  },
  actions: {
    generate({ commit }) {
      commit('generate')
    }
  },
  modules: {
  }
})

終わりに

今回は、一度JSONにする作戦で対応したけど、もっとスマートなやり方があれば知りたいです。

コメント