報錯原理解讀
Error: [vuex] Do not mutate vuex store state outside mutation handlers.
該報錯從文本意思理解還是很清晰的,不要在mutation函數外修改vuex中存儲的值。
通常情況下,vuex掛載到vue上之後,vuex中的值可以在組件中修改
this.$store.state.count = 1
但我們不推薦這種做法,這是一種代碼規範,建議不要在mutation函數外修改state的值,避免不必要的參數混亂。
至於要不要遵循這種規範,完全取決於你。vuex也很貼心的提供了嚴格模式,來控制是否提示不規範的store值修改。參考代碼:
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import getters from './getters'
import defaultState from './state'
import mutations from './mutations'
Vue.use(Vuex) // 將Vuex掛載到Vue
const debug = process.env.NODE_ENV !== 'production'
export default () => {
return new Vuex.Store({
strict: debug, // 嚴格模式,是否能在mutation外修改state值,true → 不能修改,false → 可以修改
actions,
getters,
state: defaultState,
mutations
})
}
注意:開啓了嚴格模式之後,若在mutation外修改值,也能動態渲染到頁面上,只是vue會有警告提示,類似於這樣:
試錯案例分析
出現這個Vuex報錯,通常是顯性的(真的在組件中調用了this.$store.state,並且對其進行了改變),以下介紹一種自己犯錯遇到的不易察覺的出錯方式。
項目需要使用了vux(一個Vue的移動端組件庫)中的toast組件,看官網參數如下:
vux官網:https://doc.vux.li/zh-CN/components/toast.html
toast組件文檔:
瀏覽文檔之後,一頓操作,看到文檔中寫着“使用v-model綁定”,就把代碼寫成了這樣:
// 組件中使用toast
<template>
<div>
<button @click="showToast">點我顯示toast</button>
<vux-toast v-model="vuxToast.value" :position="vuxToast.position" :type="vuxToast.type" :text="vuxToast.text"></vux-toast>
</div>
</template>
<script type="text/ecmascript-6">
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState(['vuxToast'])
},
method: {
...mapMutations(['updataVuxToast']),
showToast {
this.updataVuxToast({value: true, text: '顯示toast'})
}
}
}
</script>
// state.js
export default {
vuxToast: {
position: 'middle',
type: 'text',
value: false,
text: ''
}
}
// mutations.js
export default {
updataVuxToast (state, props) {
const vuxToast = Object.assign({}, state.vuxToast, props)
state.vuxToast = vuxToast
}
}
是不是看着完全沒問題?運行之後,toast提示正常顯示,2秒後提示關閉,這時就會促發Error: [vuex] Do not mutate vuex store state outside mutation handlers.錯誤,一臉懵,各種查找是否在其他組件修改了值。
最後注意到一點:在toast提示框關閉之後才報錯,再端詳一遍代碼,看着v-model不太對呀!
將 v-model 改成 :value
<vux-toast :value="vuxToast.value" :position="vuxToast.position" :type="vuxToast.type" :text="vuxToast.text"></vux-toast>
再次測試,完美運行!
至此,需要去惡補一下v-model的知識啦,也可以瞭解一下組件的自定義雙向綁定,對於理解這個v-model知識點非常有幫助。
還是怪自己學藝不精。
與君共勉:再牛逼的夢想,也抵不住傻逼般的堅持!