第三章: Vuex旗下的Mutation

image

寫在前面

上一講「Vuex 旗下的 State 和 Getter」压彭,告訴了我們怎么去使用倉庫 store 中的狀態(tài)數(shù)據(jù)。當然盯桦,光會用肯定還不夠绰寞,大部分的應用場景還得對這些狀態(tài)進行操控撮竿,那么具體如何操控呢,這就是這一講要說的重點骆姐。

只有 mutation 能動 State

更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation镜粤。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調(diào)函數(shù) (handler)捏题。這個回調(diào)函數(shù)就是我們實際進行狀態(tài)更改的地方,并且它會接受 state 作為第一個參數(shù):

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    // 事件類型 type 為 increment
    increment (state) {
      // 變更狀態(tài)
      state.count++
    }
  }
})

注意肉渴,我們不能直接 store.mutations.increment() 來調(diào)用公荧,Vuex 規(guī)定必須使用 store.commit 來觸發(fā)對應 type 的方法:

store.commit('increment')

傳參

我們還可以向 store.commit 傳入額外的參數(shù):

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

// 調(diào)用
store.commit('increment', 10)

mutation 中的這個額外的參數(shù),官方給它還取了一個高大上的名字:載荷(payload)同规。說實話循狰,第一次在文檔中看到這個標題「提交載荷」,真的就不想往下看了捻浦。

我們往往不是敗給了這些生澀的概念晤揣,而是敗給了自己內(nèi)心的恐懼。

大多數(shù)情況下朱灿,載荷是一個對象昧识,能夠讓我們更加易讀:

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

關(guān)于提交的方式,有兩種:

// 1盗扒、把載荷和type分開提交
store.commit('increment', {
  amount: 10
})

// 2跪楞、整個對象都作為載荷傳給 mutation 函數(shù)
store.commit({
  type: 'increment',
  amount: 10
})

當然,使用哪種方式?jīng)]有絕對的界限侣灶,純看自己的喜好甸祭,就我個人而言,還是比較傾向于使用第二種姿勢褥影,放在一起更實在池户。

修改規(guī)則

簡單修改基礎類型的狀態(tài)數(shù)據(jù)倒是簡單,沒什么限制凡怎,但是如果修改的是對象校焦,那就要注意了。比如這個例子:

const store = new Vuex.Store({
  state: {
    student: {
      name: '小明',
      sex: '女'
    }
  }
})

這個時候统倒,我們?nèi)绻胍o student 添加一個年齡 age: 18 屬性寨典,怎么辦呢?

是的房匆,直接在 sex 下面把這個字段加上去不就行了耸成,能這樣當然最好了。但是如果我們要動態(tài)的修改呢浴鸿?那就得遵循 Vue 的規(guī)則了井氢。如下:

mutations: {
  addAge (state) {
    Vue.set(state.student, 'age', 18)
    // 或者:
    // state.student = { ...state.student, age: 18 }
  }
}

以上就是給對象添加屬性的兩種方式,當然赚楚,對于已添加的對象毙沾,如果想修改具體值的話,直接更改就是宠页,比如 state.student.age=20 即可左胞。

至于為什么要這樣寇仓,之前我們了解過,因為 store 中的狀態(tài)是響應式的烤宙,當我們更改狀態(tài)數(shù)據(jù)的時候遍烦,監(jiān)視狀態(tài)的 Vue 組件也會自動更新,所以 Vuex 中的 mutation 也需要與使用 Vue 一樣遵守這些規(guī)則躺枕。

使用常量

就是使用常量來替代 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) {
      // mutate state
    }
  }
})

可能有人會有疑問啊,這樣做到底有啥用拐云,還得多創(chuàng)建個類型文件罢猪,用的時候還要導入進來,不嫌麻煩嗎叉瘩!

我們看看膳帕,mutation 是怎么調(diào)用的:store.commit('increment'),可以發(fā)現(xiàn)薇缅,這里 commit 提交的方法 increment危彩,是以字符串的形式代入的。如果項目小泳桦,一個人開發(fā)的話倒還好汤徽,但是項目大了,編寫代碼的人多了灸撰,那就麻煩了谒府,因為需要 commit 的方法一多,就會顯得特別混亂浮毯,而且以字符串形式代入的話狱掂,一旦出了錯,很難排查亲轨。

所以,對于多人合作的大項目鸟顺,最好還是用常量的形式來處理 mutation惦蚊,對于小項目倒是無所謂,想偷懶的隨意就好讯嫂。

必須是同步函數(shù)

一定要記住蹦锋,Mutation 必須是同步函數(shù)。為什么呢欧芽?

前面說了莉掂,我們之所以要通過提交 mutation 的方式來改變狀態(tài)數(shù)據(jù),是因為我們想要更明確地追蹤到狀態(tài)的變化千扔。如果像下面這樣異步的話:

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

我們就不知道什么時候狀態(tài)會發(fā)生改變憎妙,所以也就無法追蹤了库正,這與 Mutation 的設計初心相悖,所以強制規(guī)定它必須是同步函數(shù)厘唾。

store.commit('increment')
// 任何由 "increment" 導致的狀態(tài)變更都應該在此刻完成褥符。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市抚垃,隨后出現(xiàn)的幾起案子喷楣,更是在濱河造成了極大的恐慌,老刑警劉巖鹤树,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铣焊,死亡現(xiàn)場離奇詭異,居然都是意外死亡罕伯,警方通過查閱死者的電腦和手機曲伊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捣炬,“玉大人熊昌,你說我怎么就攤上這事∈幔” “怎么了婿屹?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長推溃。 經(jīng)常有香客問我昂利,道長,這世上最難降的妖魔是什么铁坎? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任蜂奸,我火速辦了婚禮,結(jié)果婚禮上硬萍,老公的妹妹穿的比我還像新娘扩所。我一直安慰自己,他們只是感情好朴乖,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布祖屏。 她就那樣靜靜地躺著,像睡著了一般买羞。 火紅的嫁衣襯著肌膚如雪袁勺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天畜普,我揣著相機與錄音期丰,去河邊找鬼。 笑死,一個胖子當著我的面吹牛钝荡,可吹牛的內(nèi)容都是我干的街立。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼化撕,長吁一口氣:“原來是場噩夢啊……” “哼几晤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起植阴,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蟹瘾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掠手,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體憾朴,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年喷鸽,在試婚紗的時候發(fā)現(xiàn)自己被綠了众雷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡做祝,死狀恐怖砾省,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情混槐,我是刑警寧澤编兄,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站声登,受9級特大地震影響狠鸳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜悯嗓,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一件舵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脯厨,春花似錦铅祸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至眯杏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間壳澳,已是汗流浹背岂贩。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萎津。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓卸伞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锉屈。 傳聞我的和親對象是個殘疾皇子荤傲,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 寫在前面 上一講「Vuex 旗下的 State 和 Getter」,告訴了我們怎么去使用倉庫 store 中的狀態(tài)...
    大宏說閱讀 29,416評論 11 89
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 730評論 0 3
  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統(tǒng)中颈渊,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 2,938評論 0 7
  • Vuex是什么遂黍? Vuex 是一個專為 Vue.js應用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應用的所有組件...
    蕭玄辭閱讀 3,118評論 0 6
  • Vuex 是什么俊嗽? Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式雾家。它采用集中式存儲管理應用的所有...
    skycolor閱讀 837評論 0 1