寫在前面
上一講「Vuex 旗下的 State 和 Getter」,告訴了我們怎么去使用倉庫 store 中的狀態資料,當然,光會用肯定還不夠,大部分的應用場景還得對這些狀態進行操控,那么具體如何操控呢,這就是這一講要說的重點,
只有 mutation 能動 State
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation,Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字串的 事件型別 (type) 和 一個 回呼函式 (handler),這個回呼函式就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個引數:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
// 事件型別 type 為 increment
increment (state) {
// 變更狀態
state.count++
}
}
})
注意,我們不能直接 store.mutations.increment() 來呼叫,Vuex 規定必須使用 store.commit 來觸發對應 type 的方法:
store.commit('increment')
傳參
我們還可以向 store.commit 傳入額外的引數:
mutations: {
increment (state, n) {
state.count += n
}
}
// 呼叫
store.commit('increment', 10)
mutation 中的這個額外的引數,官方給它還取了一個高大上的名字:載荷(payload),說實話,第一次在檔案中看到這個標題「提交載荷」,真的就不想往下看了,
我們往往不是敗給了這些生澀的概念,而是敗給了自己內心的恐懼,
大多數情況下,載荷是一個物件,能夠讓我們更加易讀:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
關于提交的方式,有兩種:
// 1、把載荷和type分開提交
store.commit('increment', {
amount: 10
})
// 2、整個物件都作為載荷傳給 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" 導致的狀態變更都應該在此刻完成,
最在最后
這一講相對來說應該還是比較好理解的,對于官方我覺得比較難理解的,我都盡量用通俗易懂的示例來進行分析,來加深大家的理解,但是不知道效果如何,如果對大家有幫助,歡迎點贊和轉載,注明出處即可,
轉載宣告:
作者:大宏說
鏈接:https://www.jianshu.com/p/64727454f151
后記
以上就是胡哥今天給大家分享的內容,喜歡的小伙伴記得點贊、收藏呦,關注胡哥有話說,學習前端不迷路,歡迎多多留言交流...
胡哥有話說,一個有技術,有情懷的胡哥!現任京東前端攻城獅一枚,
胡哥有話說,專注于大前端技術領域,分享前端系統架構,框架實作原理,最新最高效的技術實踐!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/109893.html
標籤:JavaScript
上一篇:echart 堆疊圖
下一篇:vue-cli3安裝
