vuex中store 的mutation
vuex中store 的mutation
1.mutation
官方解釋mutation:
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數
官方是建議我們通過mutation來實現更改store中的state的數據,而非在組件中直接使用store.state.data=xxx來直接進行更改。通過mutation來更改數據的操作會被捕獲到,而直接使用store.state.data=xxx來直接進行更改。通過mutation來更改數據的操作會被捕獲到,而直接使用store.state.data=xxx來直接進行更改。通過mutation來更改數據的操作會被捕獲到,而直接使用store.state.data=xxx這種方式更的數據是無法被捕獲的,如果發生錯誤,將無法定位到是哪個組件的操作導致錯誤發生,所以官方說更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。
圖示:
上網找到 一個很不錯的圖
流程:
- 繞過Actions(mutation必須是同步操作,Devtools才能追蹤變量)
- 不繞過Actions(Action 可以包含任意異步操作)
解析:
當我們只有同步操作的時候,官方允許我們在組件中直接提交mutation,而不經過Actions,但是如果我們的操作包含異步操作的時候,我們必須通過Actions來異步提交mutation,從而實現異步操作,這樣才能讓Devtools可以捕獲變量更改。
2.初次使用
const store = new Vuex.Store({state: {count: 1},mutations: {increment (state) {// 變更狀態state.count++},incrementNum (state,num) {// 通過提交載荷傳遞過來的numstate.count+=num}} })//在組件中定義一個方法通過$store.commit('increment')來進行提交 methods:{increment(){this.$store.commit('increment')},incrementNum(num){this.$store.commit('increment',num)} }3.提交載荷
mutations接受commit傳遞過來的參數,這個參數叫做payload(提交載荷),我們可以通過payload來實現數據的傳遞。
mutations: {increment (state, payload) {state.count += payload.amount} }store.commit('increment', {amount: 10 })4.對象風格的提交方式
store.commit()提供了另一種提交風格,store.commit()允許以對象的風格進行提交,這個風格跟vue很切合,對象聲明形式。
store.commit({type: 'increment', //對應commit第一個參數,也就是事件類型amount: 10 //傳遞的參數payload })使用
mutations: {increment (state, payload) { //對象提交方式,payload是提交載荷state.count += payload.amount} }5.Mutation 需遵守 Vue 的響應規則
Vuex 的 store 中的狀態是響應式的,所以Vuex 中的 mutation 也需要與使用 Vue 一樣遵守一些注意事項。
添加操作
//錯誤的示范 state.info['address']='北京'//正確的示范 Vue.set(state.info,'address','北京') //vue官方說以新對象替換老對象是遵守 Vue 的響應規則 //響應系統能捕獲全新的對象數據 state.info = {//一個全新的對象}第一個示范雖然是給state中的info添加了一個key value,但是這種添加操作是繞過了vue的響應式系統的,所以vue并沒有將新添加的key value追加到響應系統里面,所以視圖是不會動態跟新新添加的數據。
而第二種示范,是通過vue的響應式系統進行變量的追加,所以vue能監控到變量的變化,從而對視圖做出響應和跟新。
刪除操作
刪除操作同理
Vue.delete(state.info,'address')6.用常量替代Mutation事件類型
從上面的代碼可以看出,我在使用store.commit的時候后面都是通過字符串的形式來指定commit的mutation。而官方建議是將這種mutation 事件類型進行一個抽離,將這些mutation的名字定義到一個專門保存的單獨文件種,這樣做抽離,使得整個APP的mutatio易于管理,也使得項目結構清晰。
使用常量替代 mutation 事件類型在各種 Flux 實現中是很常見的模式。這樣可以使 linter 之類的工具發揮作用,同時把這些常量放在單獨的文件中可以讓你的代碼合作者對整個 app 包含的 mutation 一目了然:
官方建議的操作如下:
先將創建一個mutation-types.js,里面存儲定義的mutation 事件類型
// mutation-types.js export const SOME_MUTATION = 'SOME_MUTATION' //定義什么mutation,先將事件類型(名字)寫這里使用的時候
// store.js import Vuex from 'vuex' import { SOME_MUTATION } from './mutation-types'const store = new Vuex.Store({state: { ... },mutations: {/*官方是用這種風格來命名的:[SOME_MUTATION] (state) {} ---等價轉變--->SOME_MUTATION(state) {}*/// 我們可以使用 ES2015 風格的計算屬性命名功能來使用一個常量作為函數名[SOME_MUTATION] (state) {// mutate state}} })//其他組件commit時 import { SOME_MUTATION } from './mutation-types'... store.commit(SOME_MUTATION)7.Mutation 必須是同步函數
官方是這樣解釋的:
一條重要的原則就是要記住 mutation 必須是同步函數。為什么?請參考下面的例子:
mutations: {someMutation (state) {api.callAsyncMethod(() => {state.count++})} }現在想象,我們正在 debug 一個 app 并且觀察 devtool 中的 mutation 日志。每一條 mutation 被記錄,devtools 都需要捕捉到前一狀態和后一狀態的快照。然而,在上面的例子中 mutation 中的異步函數中的回調讓這不可能完成:因為當 mutation 觸發的時候,回調函數還沒有被調用,devtools 不知道什么時候回調函數實際上被調用——實質上任何在回調函數中進行的狀態的改變都是不可追蹤的。
所以我們為了能夠實現異步操作,我們需要借助Actions來實現,在Actions通過異步提交 mutation從而實現異步操作,Action 可以包含任意異步操作,Action 提交的是 mutation,而不是直接變更狀態。
總結
以上是生活随笔為你收集整理的vuex中store 的mutation的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微博常用表情有哪些?新浪微博常用表情排行
- 下一篇: GitHub图片无法显示