vuex?Mutations同步Actions異步原理解析
正文
vuex的mutations
與actions
有什么區(qū)別,除了用法上mutation
是同步,actions
是異步,這里的同步與異步指的是commit
ordispatch
?并不是,同步指mutations
方的內(nèi)部是同步的,而actions
內(nèi)部可以是異步的,并且修改數(shù)據(jù)只能在mutations
中修改,在actions
中異步的操作副作用是通過mutations
來記錄。本文是一篇筆者記錄vuex
關(guān)于mutations
與actions
的筆記。
避坑
如果使用vue-cli2
模版搭建的基礎(chǔ)項(xiàng)目,注意,如果使用vue
版本是2,當(dāng)你你默認(rèn)安裝vuex
肯定是4.x
版本了,這里需要注意的是,你要降低vuex
版本到3.x
版本,不然store
掛載不到vue
上
mutation
當(dāng)我們修改數(shù)據(jù),只能通過mutation
修改state
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export const store = new Vuex.Store({ state: { data: [] }, mutations: { storeData (state, payload) { state.data = state.data.concat(payload) } } })
在頁面中
import { mockFeatchData } from '@/mock' export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } }, computed: { ...mapState({ dataList: state => state.data }) }, methods: { handleData () { mockFeatchData().then(res => { this.$store.commit('storeData', res) }) } } }
我們修改數(shù)據(jù)就是$store.commit('eventName', payload)
,當(dāng)我們觸發(fā)commit
時(shí),實(shí)際上是已經(jīng)在異步請求回調(diào)里獲取了數(shù)據(jù)。
但是官方在描述mutation
有這么說,mutation
內(nèi)部必須是同步函數(shù),異步會(huì)導(dǎo)致內(nèi)部狀態(tài)難以追蹤,devtool
難以追蹤state
的狀態(tài)
... mutations: { storeData (state, payload) { mockFeatchData().then((res) => { console.log(res) state.data = state.data.concat(res) }) } },
也就是說上面這段代碼,當(dāng)我們在mutations
中的storeData
中使用了異步函數(shù),我們在$store.commit('storeData')
時(shí),很難追蹤state
的狀態(tài),因?yàn)樵谟|發(fā)commit事件時(shí),異步的回調(diào)函數(shù)不知道什么時(shí)候執(zhí)行,所以難以追蹤。
mutations
是同步事務(wù),假設(shè)在mutations
有多個(gè)異步的調(diào)用,你很難確定這些異步哪些先執(zhí)行,很難追蹤state
的變化,所以也給調(diào)試帶來了一定難度
話說回來,這么寫也確實(shí)是可以做到更新state的值,如果我不用vuetool
這個(gè)工具,貌似也沒毛病
既然mutations
是同步的事情,那么異步官方就使用了actions
方案
actions
actions
里面可以做異步操作,但是并不是直接修改數(shù)據(jù),提交的是mutations
里面的方法
mutations: { storeData (state, payload) { state.data = state.data.concat(payload) } }, actions: { setStoreData ({ commit }) { mockFeatchData().then((res) => { commit('storeData', res) }) } }
在頁面中就是這樣觸發(fā)actions
的
methods: { handleData () { this.$store.dispatch('setStoreData') } }
我們把異步操作放在了actions
的方法里面,你會(huì)發(fā)現(xiàn)mockFeatchData
這是一個(gè)異步操作后的結(jié)果,然后通過commit
傳給了mutations
中
在actions
執(zhí)行異步操作,將結(jié)果給了mutations
,mutations
中同步修改狀態(tài)state
,使得actions
的操作在mutations
中有記錄。
在actions
中也可以有多個(gè)異步操作
mutations: { storeData (state, payload) { state.data = state.data.concat(payload) }, storeText (state, payload) { state.text = payload } }, actions: { setStoreData ({ commit }) { mockFeatchData().then((res) => { console.log(res, '111') commit('storeData', res) }) }, setStoreText ({ dispatch, commit }, payload) { dispatch('setStoreData').then(() => { console.log(222) commit('storeText', payload) }) } }
頁面上是這樣觸發(fā)actions
的
handleText () { this.$store.dispatch('setStoreText', `hello,${Math.random()}`) }
這里我們也可以用對象的方式
handleText () { this.$store.dispatch({ type: 'setStoreText', payload: `hello,${Math.random()}` })
不過此時(shí)注意actions
中獲取值需要解構(gòu)才行
setStoreText ({ dispatch, commit }, {payload}) { dispatch('setStoreData').then(() => { console.log(222, payload) commit('storeText', payload) }) }
在actions可以dispatch
另一個(gè)異步的操作,也就是等一個(gè)任務(wù)完成了后,可以執(zhí)行另一個(gè)commit
看到這里貌似這里有點(diǎn)明白,為啥所有的異步操作放在actions
里面了,mutation
只負(fù)責(zé)修改state
,所有異步操作產(chǎn)生的副作用的結(jié)果都統(tǒng)統(tǒng)交給了mutation
,這樣很好保證devtool
了對數(shù)據(jù)的追蹤。
總結(jié)
靈魂拷問,為什么會(huì)有actions
中是異步,而mutations
是同步,從官方解釋來看,修改state數(shù)據(jù)必須只能mutations
中修改,而假設(shè)mutions
內(nèi)部有異步,那么會(huì)帶來devtool
無法準(zhǔn)確追蹤state
變化,因?yàn)槎鄠€(gè)異步并不知道哪個(gè)異步會(huì)先執(zhí)行完。但是話說回來,mutations
中有異步,依然可以修改state啊,因?yàn)闃I(yè)務(wù)中我并不太需要知道devtool
是如何追蹤state
的變化,但是為了遵從規(guī)范,所有的異步都在actions
中處理,mutations
只集中干一件事,直接修改state
值
actions
是異步操作的,actions
中可以有多個(gè)異步操作,但是最終的結(jié)果依然是交給mutations
去修改的,也就是說actions
中異步操作的副作用統(tǒng)一交給了mutations
去記錄
多個(gè)異步任務(wù)可以在actions
中觸發(fā),dispatch('xxx')
返回的是一個(gè)Promise
以上就是vuex Mutations同步Actions異步原理解析的詳細(xì)內(nèi)容,更多關(guān)于vuex Mutations Actions的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue+element實(shí)現(xiàn)表單校驗(yàn)功能
這篇文章主要介紹了vue+element表單校驗(yàn)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05vscode搭建vue環(huán)境完整圖文教程(適合新手小白)
Vue框架的優(yōu)秀設(shè)計(jì)和強(qiáng)大的生態(tài)系統(tǒng)成為了越來越多開發(fā)者選擇Vue的原因,在實(shí)際項(xiàng)目過程中一個(gè)高效的開發(fā)環(huán)境能夠大大提高開發(fā)效率,這篇文章主要給大家介紹了關(guān)于vscode搭建vue環(huán)境的相關(guān)資料,需要的朋友可以參考下2023-10-10vue新建項(xiàng)目并配置標(biāo)準(zhǔn)路由過程解析
這篇文章主要介紹了vue新建項(xiàng)目并配置標(biāo)準(zhǔn)路由過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12Vue3項(xiàng)目中使用防抖節(jié)流的實(shí)現(xiàn)示例
防抖節(jié)流是可以說是一種優(yōu)化組件性能的技巧,可以有效減少組件中的渲染次數(shù)和計(jì)算量,本文主要介紹了Vue3項(xiàng)目中使用防抖節(jié)流的實(shí)現(xiàn)示例,感興趣的可以了解一下2024-04-04使用Vue3和Plotly.js打造一個(gè)3D圖在線展示的實(shí)現(xiàn)步驟
三維網(wǎng)格圖廣泛應(yīng)用于科學(xué)可視化、醫(yī)學(xué)成像、工程設(shè)計(jì)等領(lǐng)域,用于展示復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和空間分布,本文給大家介紹了使用Vue3和Plotly.js打造一個(gè)3D圖在線展示的實(shí)現(xiàn)步驟,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2024-07-07vue父組件與子組件之間的數(shù)據(jù)交互方式詳解
最近一直在做一個(gè)vue移動(dòng)端商城的實(shí)戰(zhàn),期間遇到一個(gè)小小的問題,值得一說,下面這篇文章主要給大家介紹了關(guān)于vue父組件與子組件之間數(shù)據(jù)交互的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11