Vue.js:Vuexのエラー(vuex do not mutate vuex store outside mutation handlers)対策

ストアに定義したステートをcomputed経由で連想配列の任意のキーに対して値をForループ内で変更しようしたら、「vuex do not mutate vuex store outside mutation handlers」が発生して困ったので、解消方法を残しておく。直訳すると「ミューテーションハンドラーの外部でvuexストアの状態をミューテーションしないでください」と言っているみたい。

エラー画像イメージ

環境

  • Visual Studio Code:1.61.2
  • Vue:2.6.12
  • Nuxt.js:2.14.5
  • Vuex-persistedstate:4.0.0

やりたかったこと

ストア(store)に格納されている配列の要素を変更したかった。Vuex的にはストア内のステートの状態を変更したかった。

問題のソース

forループ内でミューテーション内で返す配列内部の要素の値を変更(★)すると、 「vuex do not mutate vuex store outside mutation handlers」 が発生。本コードを削除して実行した場合は、エラーは発生しなかった。

つまるところ、 ミューテーションハンドラー外では値の更新できないということだと思う。(メッセージ通り)

 computed: {
     // 連想配列
     tableArrayData: {
       get () {
         return this.$store.getters['teststore.js/getTableArrayData']
       },
       set (value) {
         this.$store.commit('teststore.js/setTableArrayData', value)
       }
     },
 ・・・・
//inputタグで値が変更されたときにアクションするメソッド
sumtotal () {

      for (let i = 0; i < this.tableArrayData.length; i++) {
          this.tableArrayData[i].quantity = 1 //★ストアのミーテーションの配列を直接操作するとエラーが発生。
      }
     
},

test.vue

ストアファイル( teststore.js )

// storeのステート宣言
export const state = () => ({
  // 連想配列
  tableArrayData: [],
})
 
// storeのステート変更定義
export const mutations = {
  setTableArrayData (state, input) {
    state.tableArrayData = input
  }
}
 
// storeのステート取得
export const getters = {
  getTableArrayData (state) {
    return state.tableArrayData
  }
}

解消方法1

ミューテーション( computed )の連想配列を値渡しで、ローカル変数にセットし要素内の値を更新したあと、再度、ストア( ミューテーション( computed ) )にセットするという方法。

その際、気を付けなければならないのが、通常の=(イコール)でセットした場合は、参照渡しとなってしまう。そこで、JSON化して文字列に変換し、それをJSONパースしオブジェクトに変換したものを変数にセットして解決した。

配列を ストア( ミューテーション( computed ) ) にセットする分には問題ないので。

 computed: {
     // 連想配列
     tableArrayData: {
       get () {
         return this.$store.getters['teststore.js/getTableArrayData']
       },
       set (value) {
         this.$store.commit('teststore.js/setTableArrayData', value)
       }
     },
 ・・・・
//inputタグで値が変更されたときにアクションするメソッド
sumtotal () {
      let tmptabledata = []             //★追加
      tmptabledata = JSON.parse(JSON.stringify(this.tableArrayData))//★追加

      for (let i = 0; i < this.tableArrayData.length; i++) {
          tmptabledata[i].quantity = 1  //★ローカル変数(連想配列)に修正
      }
      this.tableArrayData= tmptabledata //★追加 ストアファイルに再セット
     
},

解消方法2

ストアファイル内にミューテーション(mutations)として定義して、その内部でステートの配列内の要素を変更する方法。この方法は、まだ検証していないので、可能性の一環として残しておく。