[Vuex系列] - Actions的理解之我見

Actions如何定義的

恕小端不才,對Action的總結以下:vue

  • Action 能夠提交mutation方法,經過mutation來改變state
  • Action 函數能夠接收一個context對象,經過context.state 和 context.getters來改變state。(在實際工做中不經常使用)
  • Action 能夠執行任意的同步和異步操做

接下來咱們經過上面三點總結來看Actions的使用:vuex

Action 能夠提交mutation方法,經過mutation來改變state

咱們先在actions.js定義一個addCountAction方法用來作累加器bash

const actions = {
  addNumAction (context, num) {
    context.commit('addNum', num)
  },
  addCountAction (context) {
    context.commit('add')
  }
}
export default actions
複製代碼

在組件中經過.dispatch進行分發Actions,內容以下:異步

<template>
  <div class="action">
    <p>{{ count }}</p>
    <button @click="add">+ADD</button>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  data () {
    return {}
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    add () {
      this.$store.dispatch('addCountAction')
    }
  }
}
</script>
複製代碼

Action 函數能夠接收一個context對象,經過context.state 和 context.getters來改變state。(不推薦使用)

在actions.js中定義一個新方法reduceCountAction方法,實現一個累減async

const actions = {
  addNumAction (context, num) {
    context.commit('addNum', num)
  },
  addCountAction (context) {
    context.commit('add')
  },
  reduceCountAction (context) {
    context.state.count--
  }
}
export default actions
複製代碼

在組件中經過.dispatch進行分發Actions,內容以下:函數

<template>
  <div class="action">
    <button @click="reduce">-REDUCE</button>
    <p>{{ count }}</p>
    <button @click="add">+ADD</button>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  data () {
    return {}
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    add () {
      this.$store.dispatch('addCountAction')
    },
    reduce () {
      this.$store.dispatch('reduceCountAction')
    }
  }
}
</script>
複製代碼

Action 能夠執行任意的同步和異步操做

咱們將actions.js中的addCountAction函數修改以下:post

addCountAction (context) {
    setTimeout(function () {
      context.commit('add')
    }, 2000)
}
複製代碼

修改後咱們發如今執行累加的時候,會等待兩秒纔會執行。ui

在組件中使用mapActions 輔助函數

將以前的組件addCountAction函數用輔助函數替代,修改以下:this

<template>
  <div class="action">
    <button @click="reduce">-REDUCE</button>
    <p>{{ count }}</p>
    <button @click="addCountAction">+ADD</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex'
export default {
  data () {
    return {}
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['addCountAction']),
    reduce () {
      this.$store.dispatch('reduceCountAction')
    }
  }
}
</script>

複製代碼

組合Actions的使用

Action一般是異步的,那麼如何知道action何時結束呢?更重要的是,咱們如何才能組合多個action,以處理更加複雜的異步流程?spa

首先,你須要明白 store.dispatch 能夠處理被觸發的 action 的處理函數返回的 Promise,而且 store.dispatch 仍舊返回 Promise:

const actions = {
  addNumAction (context, num) {
    context.commit('addNum', num)
  },
  addCountAction (context) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        context.commit('add')
        resolve()
      }, 1000)
    })
  },
  reduceCountAction (context) {
    context.state.count--
  },
  addTwoAction (context) {
    context.dispatch('addCountAction').then(() => {
      context.commit('addTwo')
    })
  }
}
export default actions

複製代碼

在上面咱們在addTwoAction函數中實現了一個組合的actions

  • 若是咱們利用 async / await,咱們能夠以下組合 action
// 假設 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在不一樣模塊中能夠觸發多個action函數。在這種狀況下,只有當全部觸發函數完成後,返回的Promise纔會執行。

最後,咱們說下官方的定義,在官網是這樣定義的Actions:

  • Action 相似於 mutation,不一樣在於:
  • Action 提交的是 mutation,而不是直接變動狀態。
  • Action 能夠包含任意異步操做。

1、[Vuex系列] - 初嘗Vuex第一個例子

2、[Vuex系列] - 細說state的幾種用法

3、[Vuex系列] - Mutation的具體用法

4、[Vuex系列] - getters的用法

5、[Vuex系列] - Actions的理解之我見

6、[Vuex系列] - Module的用法(終篇)

相關文章
相關標籤/搜索