Vuex之Action的使用方法詳解
Action 可以包含任意異步操作,需要的朋友可以參考下
前言
在 mutation 中混合異步調(diào)用會導致你的程序很難調(diào)試。例如,當你調(diào)用了兩個包含異步回調(diào)的 mutation 來改變狀態(tài),你怎么知道什么時候回調(diào)和哪個先回調(diào)呢?這就是為什么我們要區(qū)分這兩個概念。在 Vuex 中,mutation 都是同步事務(wù):
store.commit('add')// 任何由 "add" 導致的狀態(tài)變更都應(yīng)該在此刻完成。
因此,Action 就出現(xiàn)了。
一、什么是 Action
Action 類似于 mutation ,不同在于:
- Action 提交的是 mutation,而不是直接變更狀態(tài)。
- Action 可以包含任意異步操作。
讓我們來注冊一個簡單的 action:
const store = new Vuex.Store({ state: { count: 0 }, mutations: { add(state) { state.count++ } }, actions: { add(context) { context.commit('add') } } })
Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調(diào)用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters。當我們在之后介紹到 Modules 時,你就知道 context 對象為什么不是 store 實例本身了。
實踐中,我們會經(jīng)常用到 ES2015 的 參數(shù)解構(gòu) (opens new window)來簡化代碼(特別是我們需要調(diào)用 commit 很多次的時候):
actions: { add({ commit }) { commit('add') } }
二、分發(fā) Action(調(diào)用 Action)
Action 通過 store.dispatch 方法觸發(fā):
store.dispatch('add')
乍一眼看上去感覺多此一舉,我們直接分發(fā) mutation 豈不更方便?實際上并非如此,因為 mutation 必須同步執(zhí)行.。Action 就不受約束!我們可以在 action 內(nèi)部執(zhí)行異步操作:
actions: { addAsync ({ commit }) { setTimeout(() => { commit('add') }, 1000) } }
Actions 支持同樣的 載荷方式和對象方式進行分發(fā):
// 以載荷形式分發(fā) store.dispatch('addAsync', { amount: 10 }) // 以對象形式分發(fā) store.dispatch({ type: 'addAsync', amount: 10 })
三、在組件中分發(fā) Action
在組件中使用 this.$store.dispatch('xxx') 分發(fā) action,或者使用 mapActions 輔助函數(shù)將組件的 methods 映射為 store.dispatch 調(diào)用(需要先在根節(jié)點注入 store):
// main.js // 根節(jié)點引入store new Vue({ el: '#app', store })
// 組件 import { mapActions } from 'vuex' export default { methods: { // 將 `this.add()` 映射為 `this.$store.dispatch('add')` // `mapActions` 也支持載荷: // 將 `this.addBy(amount)` 映射為 `this.$store.dispatch('addBy', amount)` ...mapActions(['add', 'addBy']), // 將 `this.increment()` 映射為 `this.$store.dispatch('add')` ...mapActions({ increment: 'add' }) } }
四、組合 Action
Action 通常是異步的,那么如何知道 action 什么時候結(jié)束呢?更重要的是,我們?nèi)绾尾拍芙M合多個 action,以處理更加復(fù)雜的異步流程?
首先,你需要明白 store.dispatch 可以處理被觸發(fā)的 action 的處理函數(shù)返回的 Promise,并且 store.dispatch 仍舊返回 Promise:
actions: { actionA ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit('someMutation') resolve() }, 1000) }) } }
現(xiàn)在你可以調(diào)用
store.dispatch('actionA').then(() => { // 成功操作 })
在另外一個 action 中也可以:
actions: { actionB ({ dispatch, commit }) { return dispatch('actionA').then(() => { commit('someOtherMutation') }) } }
最后,如果我們利用 async / await我們可以如下組合 action:
// 假設(shè) getData() 和 getOtherData() 返回的是 Promise actions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 等待 actionA 完成 commit('gotOtherData', await getOtherData()) } }
一個store.dispatch 在不同模塊中可以觸發(fā)多個 action 函數(shù)。在這種情況下,只有當所有觸發(fā)函數(shù)完成后,返回的 Promise 才會執(zhí)行。
到此這篇關(guān)于Vuex之Action的使用方法詳解的文章就介紹到這了,更多相關(guān)Vuex的Action內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
手把手教你寫一個vue全局注冊的Toast的實現(xiàn)
本文主要介紹了手把手教你寫一個vue全局注冊的Toast的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04關(guān)于在vscode使用webpack指令顯示"因為在此系統(tǒng)中禁止運行腳本"問題(完美解決)
這篇文章主要介紹了解決在vscode使用webpack指令顯示"因為在此系統(tǒng)中禁止運行腳本"問題,本文給大家分享完美解決方法,需要的朋友可以參考下2021-07-07基于Vue+elementUI實現(xiàn)動態(tài)表單的校驗功能(根據(jù)條件動態(tài)切換校驗格式)
這篇文章主要介紹了Vue+elementUI的動態(tài)表單的校驗(根據(jù)條件動態(tài)切換校驗格式),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04使用Element時默認勾選表格toggleRowSelection方式
這篇文章主要介紹了使用Element時默認勾選表格toggleRowSelection方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10Vue3數(shù)據(jù)更新,頁面沒有同步更新的問題及解決
這篇文章主要介紹了Vue3數(shù)據(jù)更新,頁面沒有同步更新的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03