vue-vuex中使用commit提交mutation來(lái)修改state的方法詳解
在vuex中,關(guān)于修改state的方式,需要commit提交mutation。官方文檔中有這么一句話(huà):
更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation。
為了搞清楚其原因,查閱了很多資料,發(fā)現(xiàn)其它人在做vuex的源碼解析的時(shí)候,并沒(méi)有將這點(diǎn)說(shuō)的很明白。
所以只好自己去查看vuex的源碼,并且自己做demo進(jìn)行驗(yàn)證。
但是試驗(yàn)后,發(fā)現(xiàn)直接修改state時(shí),store中的state能夠改變,并且是響應(yīng)式的,并沒(méi)有報(bào)錯(cuò)。跟commit提交mutation的方式?jīng)]啥區(qū)別。
后來(lái)在github上遇到一位朋友,提醒試試嚴(yán)格模式下會(huì)發(fā)生什么。
一、兩種修改state方式的區(qū)別
在vuex官方文檔上看到了關(guān)于嚴(yán)格模式的描述:
開(kāi)啟嚴(yán)格模式,僅需在創(chuàng)建 store 的時(shí)候傳入 strict: true;
在嚴(yán)格模式下,無(wú)論何時(shí)發(fā)生了狀態(tài)變更且不是由 mutation 函數(shù)引起的,將會(huì)拋出錯(cuò)誤。這能保證所有的狀態(tài)變更都能被調(diào)試工具跟蹤到。
于是,將vuex設(shè)置成了嚴(yán)格模式。
直接修改state發(fā)現(xiàn)控制臺(tái)確實(shí)是報(bào)出了錯(cuò)誤,但是state修改成功,并且依然是響應(yīng)式的。
錯(cuò)誤提示:
Do not mutate vuex store state outside mutation handlers.
通過(guò)commit 提交 mutation 的方式來(lái)修改 state 時(shí),vue的調(diào)試工具能夠記錄每一次state的變化,這樣方便調(diào)試。但是如果是直接修改state,則沒(méi)有這個(gè)記錄。
commit修改state源碼分析
以上已經(jīng)討論了在嚴(yán)格模式下,直接修改state會(huì)造成報(bào)錯(cuò)。接下來(lái)通過(guò)分析源碼來(lái)一探究竟。
首先應(yīng)該分析commit函數(shù)的代碼,因?yàn)閙utation是通過(guò)commit函數(shù)來(lái)執(zhí)行的。
在commit函數(shù)內(nèi)部,由this._commit()函數(shù)來(lái)修改state。那么 _withCommit 又是什么呢,接著看 _withCommit 的代碼:
_withCommit 函數(shù)的參數(shù) fn 就是修改state的函數(shù)。在執(zhí)行 fn() 之前,會(huì)將 this._committing 設(shè)置為 true。等到fn()執(zhí)行完畢后,又將 this._committing 的值進(jìn)行恢復(fù)。那么為什么要將 this._withCommitting設(shè)置為true,其作用到底是什么。在vuex/src/store.js 的開(kāi)頭發(fā)現(xiàn)了判斷嚴(yán)格模式的代碼:
這三行代碼很簡(jiǎn)單:當(dāng) vuex設(shè)置為嚴(yán)格模式的時(shí)候,就會(huì)執(zhí)行 enableStrictMode 函數(shù)。那么 enableStrictMode 又是什么鬼?
在 enableStrictMode 函數(shù)內(nèi)部,調(diào)用了 $watch 函數(shù)來(lái)觀(guān)察 state的變化。當(dāng)state變化時(shí),就會(huì)調(diào)用 assert 函數(shù),判斷 store._committing(即 上文的 this._committing) 的值,如果不為 true,就會(huì)報(bào)出異常:
Do not mutate vuex store state outside mutation handlers.
所以,如果通過(guò)外部直接修改state,則沒(méi)有執(zhí)行 commit 函數(shù),也就沒(méi)有執(zhí)行 _withCommit 函數(shù),進(jìn)而 this._withCommitting 的值 不為 true,故當(dāng)執(zhí)行 enableStrictMode 時(shí),則會(huì)執(zhí)行 assert 函數(shù),因?yàn)開(kāi)withCommitting不為true,則報(bào)出異常了。
結(jié)語(yǔ)
綜上所述,在vuex中,最好設(shè)置成嚴(yán)格模式,并且按照文檔的要求,通過(guò)commit提交mutation的方式來(lái)修改state,而不要直接修改state。不然,控制臺(tái)會(huì)報(bào)錯(cuò),并且vue調(diào)試工具不會(huì)記錄state的變化,無(wú)法調(diào)試。
以上這篇vue-vuex中使用commit提交mutation來(lái)修改state的方法詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue-router 中hash模式和history模式的區(qū)別
這篇文章主要介紹了Vue-router 中hash模式和history模式的區(qū)別,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07layui實(shí)際項(xiàng)目使用過(guò)程中遇到的兼容性問(wèn)題及解決
這篇文章主要介紹了layui實(shí)際項(xiàng)目使用過(guò)程中遇到的兼容性問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04vue?elementui動(dòng)態(tài)添加el-input實(shí)例代碼
最近遇到一個(gè)新的需求,需要?jiǎng)討B(tài)添加el-input,這篇文章主要給大家介紹了關(guān)于vue?elementui動(dòng)態(tài)添加el-input的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06如何使用vue-json-viewer插件展示JSON格式數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于如何使用vue-json-viewer插件展示JSON格式數(shù)據(jù)的相關(guān)資料,Vue-json-viewer是一個(gè)Vue組件,用于在Vue應(yīng)用中顯示JSON數(shù)據(jù)的可視化工具,需要的朋友可以參考下2023-11-11