亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

characters

Vuex Mutations


在 Vuex store 中,實際改變 狀態(tài)(state) 的唯一方式是通過 提交(commit) 一個 mutation。 Vuex 的 mutation 和事件系統(tǒng)非常相似:每個 mutation 都有一個字符串 類型(type) 和 一個 回調(diào)函數(shù)(handler)?;卣{(diào)函數(shù)是我們執(zhí)行實際修改狀態(tài)的地方,它將接收 狀態(tài)(state) 作為第一個參數(shù)。

const store = new Vuex.Store({
 state: {
   count: 1
 },
 mutations: {
   increment (state) {
     // 改變 state
     state.count++
   }
 }
})

你不能直接調(diào)用 mutation 的回調(diào)函數(shù)。選項 mutations 在這里更像是注冊事件:“當觸發(fā)類型為 increment 的 mutation 時,執(zhí)行其回調(diào)函數(shù)?!彼阅阈枰{(diào)用該類型的 store.commit 才能執(zhí)行 mutation 的回調(diào)函數(shù)。

store.commit('increment')

Commit 傳入 Payload

store.commit 傳遞一個額外的參數(shù),這個參數(shù)被稱為 payload

// ...
mutations: {
 increment (state, n) {
   state.count += n
 }
}

多數(shù)情況下,payload 應(yīng)該是一個對象,以便它可以包含多個字段,這樣 mutation 記錄中有了 payload 字段名,可描述性會變得更好。

// ...
mutations: {
 increment (state, payload) {
   state.count += payload.amount
 }
}
store.commit('increment', {
 amount: 10
})

對象風(fēng)格的 Commit

提交 mutation 的另一種替代方式,是直接使用具有 type 屬性的對象:

store.commit({
 type: 'increment',
 amount: 10
})

當使用對象風(fēng)格的 commit,整個對象都會被作為 payload 參數(shù)傳入到對應(yīng)類型的 mutation 的回調(diào)函數(shù)中,不過回調(diào)函數(shù)還保持不變:

mutations: {
 increment (state, payload) {
   state.count += payload.amount
 }
}

靜默的 Commit

注意:一旦我們實現(xiàn)了 devtools 中過濾 mutation,此特性可能會被棄用。

默認情況下,每個提交過的 mutation 都會被發(fā)送到插件(如 devtools)。然而在某些情況下,你可能不希望插件去記錄每個狀態(tài)更改。像是在短時間多次提交到 store 或輪詢,并不總是需要跟蹤。在這種情況下你可以在 store.commit 中傳入第三個參數(shù),來指定插件中的 mutation 是否“靜默”。

store.commit('increment', {
 amount: 1
}, { silent: true })
// 使用對象風(fēng)格的 dispatch
store.commit({
 type: 'increment',
 amount: 1
}, { silent: true })

遵循 Vue 響應(yīng)式規(guī)則

由于 Vue 中 Vuex store 的狀態(tài)是響應(yīng)式的,當我們改變狀態(tài),Vue 組件觀察到狀態(tài)改變將自動更新。這也意味著 Vuex mutation 同樣遵循純 Vue 響應(yīng)式規(guī)則。

  1. 推薦預(yù)先初始化 store 中你所需的初始狀態(tài)。

  2. 向?qū)ο筇砑有碌膶傩詴r,你應(yīng)該這樣做:

    • 使用 Vue.set(obj, 'newProp', 123)

    • 用新的對象替換該對象。例如,使用 stage-2 對象擴展語法 我們可以這樣寫:

    1. state.obj = { ...state.obj, newProp: 123

用常量命名 Mutation

在各種 Flux 實現(xiàn)中,使用常量作為 mutation 類型是一種常見的模式。這允許代碼利用工具如 linters,將所有常量放在一個單獨文件中,盡可能使協(xié)作者對整個應(yīng)用的 mutation 一目了然。

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
 state: { ... },
 mutations: {
   // 我們能夠通過使用“ES2015 屬性名表達式”功能,來使用常量作為函數(shù)名稱
   [SOME_MUTATION] (state) {
     // 改變狀態(tài)
   }
 }
})

是否使用常量在很大程度上是一個偏好 - 在多人合作開發(fā)的大型項目中它很有用,但如果你不喜歡使用,它也是完全可選的。

Mutation 必須是同步函數(shù)

一個重要的原則就是牢記 mutation 必須是同步函數(shù)。為什么?考慮下面的例子:

mutations: {
 someMutation (state) {
   api.callAsyncMethod(() => {
     state.count++
   })
 }
}

現(xiàn)在想象我們正在調(diào)試應(yīng)用程序,并查看 devtool 的 mutation 記錄。每個 mutation 記錄,devtool 將需要捕獲每個狀態(tài)“之前”和“之后”的快照。然而,上面的示例中 mutation 內(nèi)部的異步回調(diào)使得這是不可能的:當 mutation 被提交后,回調(diào)函數(shù)還未被調(diào)用,也沒有辦法讓 devtool 知道回調(diào)函數(shù)在何時被調(diào)用 - 即在回調(diào)函數(shù)中執(zhí)行任意狀態(tài)變更,實際上都無法跟蹤。

組件中提交 Mutation

可以在組件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 工具遍歷組件方法到 store.commit 的回調(diào)上(需要把 store 注入根組件)

import { mapMutations } from 'vuex'
export default {
 // ...
 methods: {
   ...mapMutations([
     'increment' // 映射 this.increment() 到 this.$store.commit('increment')
   ]),
   ...mapMutations({
     add: 'increment' // 映射 this.add() 到 this.$store.commit('increment')
   })
 }
}

下一步:Actions

在 mutation 中混合異步調(diào)用會導(dǎo)致你的程序很難調(diào)試。例如當你調(diào)用兩個都含有異步回調(diào)的方法去改變狀態(tài),你如何知道他們何時被調(diào)用和哪個回調(diào)被首先調(diào)用?這正是我們分離 Mutation 和 Action 這兩個概念的原因。在 Vuex,Mutation 必須是同步事務(wù)

store.commit('increment')
// 類型為 "increment" 的 mutation 提交后,可能引起的任意狀態(tài)變化,都應(yīng)該在此時同步完成

為了處理異步操作,接下來我們介紹 Actions。

Previous article: Next article: