上一講「Vuex 旗下的 State 和 Getter」,告訴了咱們怎麼去使用倉庫 store 中的狀態數據。固然,光會用確定還不夠,大部分的應用場景還得對這些狀態進行操控,那麼具體如何操控呢,這就是這一講要說的重點。前端
**更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。**Vuex 中的 mutation 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數:vue
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
// 事件類型 type 爲 increment
increment (state) {
// 變動狀態
state.count++
}
}
})
複製代碼
注意,咱們不能直接 store.mutations.increment()
來調用,Vuex 規定必須使用 store.commit
來觸發對應 type 的方法:vuex
store.commit('increment')
複製代碼
咱們還能夠向 store.commit 傳入額外的參數:api
mutations: {
increment (state, n) {
state.count += n
}
}
複製代碼
// 調用 store.commit('increment', 10) mutation 中的這個額外的參數,官方給它還取了一個高大上的名字:載荷(payload)。說實話,第一次在文檔中看到這個標題**「提交載荷」**,真的就不想往下看了。bash
咱們每每不是敗給了這些生澀的概念,而是敗給了本身心裏的恐懼。架構
大多數狀況下,載荷是一個對象,可以讓咱們更加易讀:框架
mutations: { increment (state, payload) { state.count += payload.amount } } 關於提交的方式,有兩種:異步
// 一、把載荷和type分開提交
store.commit('increment', {
amount: 10
})
// 二、整個對象都做爲載荷傳給 mutation 函數
store.commit({
type: 'increment',
amount: 10
})
複製代碼
固然,使用哪一種方式沒有絕對的界限,純看本身的喜愛,就我我的而言,仍是比較傾向於使用第二種姿式,放在一塊兒更實在。函數
簡單修改基礎類型的狀態數據卻是簡單,沒什麼限制,可是若是修改的是對象,那就要注意了。好比這個例子:學習
const store = new Vuex.Store({
state: {
student: {
name: '小明',
sex: '女'
}
}
})
複製代碼
這個時候,咱們若是想要給 student
添加一個年齡age: 18
屬性,怎麼辦呢?
是的,直接在 sex
下面把這個字段加上去不就好了,能這樣固然最好了。可是若是咱們要動態的修改呢?那就得遵循 Vue 的規則了。以下:
mutations: {
addAge (state) {
Vue.set(state.student, 'age', 18)
// 或者:
// state.student = { ...state.student, age: 18 }
}
}
複製代碼
以上就是給對象添加屬性的兩種方式,固然,對於已添加的對象,若是想修改具體值的話,直接更改就是,好比state.student.age=20
便可。
至於爲何要這樣,以前咱們瞭解過,由於 store 中的狀態是響應式的,當咱們更改狀態數據的時候,監視狀態的 Vue 組件也會自動更新,因此 Vuex 中的 mutation 也須要與使用 Vue 同樣遵照這些規則。
就是使用常量來替代 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 風格的計算屬性命名功能來使用一個常量做爲函數名
[SOME_MUTATION] (state) {
// mutate state
}
}
})
複製代碼
可能有人會有疑問啊,這樣作到底有啥用,還得多建立個類型文件,用的時候還要導入進來,不嫌麻煩嗎!
咱們看看,mutation 是怎麼調用的:store.commit('increment')
,能夠發現,這裏 commit 提交的方法increment
,是以字符串的形式代入的。若是項目小,一我的開發的話倒還好,可是項目大了,編寫代碼的人多了,那就麻煩了,由於須要 commit 的方法一多,就會顯得特別混亂,並且以字符串形式代入的話,一旦出了錯,很難排查。
因此,對於多人合做的大項目,最好仍是用常量的形式來處理 mutation,對於小項目卻是無所謂,想偷懶的隨意就好。
必定要記住,Mutation 必須是同步函數。爲何呢?
前面說了,咱們之因此要經過提交 mutation 的方式來改變狀態數據,是由於咱們想要更明確地追蹤到狀態的變化。若是像下面這樣異步的話:
mutations: {
someMutation (state) {
api.callAsyncMethod(() => {
state.count++
})
}
}
複製代碼
咱們就不知道何時狀態會發生改變,因此也就沒法追蹤了,這與 Mutation 的設計初心相悖,因此強制規定它必須是同步函數。
store.commit('increment')
// 任何由 "increment" 致使的狀態變動都應該在此刻完成。
複製代碼
這一講相對來講應該仍是比較好理解的。對於官方我以爲比較難理解的,我都儘可能用通俗易懂的示例來進行分析,來加深你們的理解,可是不知道效果如何。若是對你們有幫助,歡迎點贊和轉載,註明出處便可。
轉載聲明:
做者:大宏說 連接:www.jianshu.com/p/64727454f…
以上就是胡哥今天給你們分享的內容,喜歡的小夥伴記得點贊
、收藏
呀,關注胡哥有話說,學習前端不迷路,歡迎多多留言交流...
胡哥有話說,一個有技術,有情懷的胡哥!現任京東前端攻城獅一枚。 胡哥有話說,專一於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術實踐!