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)として定義して、その内部でステートの配列内の要素を変更する方法。この方法は、まだ検証していないので、可能性の一環として残しておく。