直接看官方文檔很清楚https://vuex.vuejs.org/zh/guide/
說實話官網看的不是很懂,方便自己理解記錄幾個為什么;
1、流程
1.定義state變量
2.只有 mutations下面定義的mutation方法 能動 State,改變State
3.我們不能直接 store.mutations.increment()
來調用方法,Vuex 規定必須使用 store.commit
來觸方法,官方解釋如下圖
總結,想要改變一個 State,必須要定義一個mutation函數去改變它,想要執行mutation函數必須使用 store.commit
來觸發/調用,而不能直接 store.mutations.increment()
來調用方法;
2、為什么要通過提交 mutation 的方式來改變狀態數據?
是因為我們想要更明確地追蹤到狀態的變化,如果你隨便在一個地方就改了state.count這個屬性的狀態,項目大了的話,那就很難明確地追蹤到狀態的變化
定義mutation方法之后,想要追蹤直接在方法里面調試記錄就行了;
3、actions是干嘛的?直接用mutation改狀態不就行了,還多此一舉用actions去執行mutation去改State
首先你要知道mutation必須是同步函數(官方規定的,也就是函數里面不能有異步操作),所以想要異步操作就要action函數來處理,這就需要actions了;注意action提交的是 mutation,而不是直接變更狀態
為什么mutation必須是同步函數?
當然你說我在mutation函數里面操作異步啥的也不會報錯也沒事啊?
是在mutation中執行異步操作並不會報錯,也能正確更改狀態,所以並不是所謂的“必須同步執行”這么苛刻,只能說你最好不要這么做,你非要這么做也沒人說你,但是在 mutation 中混合異步調用會導致你的程序很難調試。
看下圖官方解釋:
1)如果像上圖這樣異步的話,我們就不知道什么時候狀態會發生改變,所以也就無法追蹤了,這與 Mutation 的設計初心相悖,所以強制規定它必須是同步函數。
2)上面的什么debug之類的我看得也有些懵,只能大概理解一下,比如想要調試console.log()打印一下state.count這個屬性改變狀態前是什么值,改變狀態后是什么值
如果沒有加那個異步函數,那就直接能打印出count改變前是0, count++改變后就是1,很方便就能調試到了。
現在搞一個異步函數在那,mutation函數已經觸發了,那個異步回調函數還沒有被調用,所以也就不知道什么時候才觸發count++,就導致很難追蹤調試;
3)假如異步操作是在action下面進行,那追蹤調試的時候只要在mutation函數里面調試,就能很直觀的知道state.count這個屬性改變狀態前后了;
4、提交載荷是啥意思 ?蒙蔽中。。啥生澀的詞語;
就是官方給它取了一個高大上的名字:載荷(payload),下面的commit第二個參數就是載荷,大多數情況下,載荷是一個對象,也就是傳一個對象進去;
5、vuex 的dispatch和commit提交mutation的區別
說白了就是在mutations下面定義的函數方法,就用commit觸發執行,在actions下面定義的方法就用dispatch觸發執行
store.commit('你的mutation方法),所以commit就是觸發mutations下面定義的方法(注意,我們不能直接 store.mutations.increment()
來調用,Vuex 規定必須使用 store.commit
來觸發對應 type 的方法:)
store.dispatch('你的action方法'), 所以dispatch就是觸發actions下面定義的方法
可以試一試用dispatch調用mutations下面定義的方法,會不會報錯反正我沒試過;
6、vuex和localstorage的區別
1)最重要的區別:vuex存儲在內存,localstorage則以文件的方式存儲在本地
2)應用場景:vuex用於組件之間的傳值,localstorage則主要用於不同頁面之間的傳值。
3)永久性:當刷新頁面時vuex存儲的值會丟失,localstorage不會。
4)ocalStorage用來存儲需要持久化的數據,vuex啟動時直接從localstorage獲取持久化的數據就實現了應用的持久化的需求
7、為什么要使用vuex而不使用全局變量比如window;
用全局變量初期還好,如果項目復雜你定義的window各種變量就很亂,你就要對這個全局變量進行封裝管理優化,更方便的調用,到最后你發現這個過程實際就是重復的造輪子,自己封裝成了個vuex,何必呢;