概念

  • action 提交 mutation ,不直接改变状态
  • action 函数的预置参数 context,是一个与store 具有相同方法和属性的 对象,但不是 store 实例本身
  • 可以 调用 context.commit 提交一个 mutation,或者通过 context.store 和 context.getters 来获取 store 和 getters

实践中,通过参数解构来简化代码

  1. action:{
  2. increment({commit}){
  3. // 调用 事件类型为 'increment'的 mutation,提交的载荷为 2
  4. commit('increment',2)
  5. }
  6. }
  7. // 购物车实例,涉及调用异步api和分发多重 mutation
  8. action:{
  9. checkout({c
  10. // 成功操作omit, state}, products){
  11. // 把当前购物车的物品备份起来
  12. const savedCartItems = [...store.cart.added]
  13. // 发出结账请求,然后清空购物车
  14. commit(types.CHECKOUT_REQUEST)
  15. // 购物车 api 接受 一个成功回调 一个 失败回调
  16. shop.buyProducts(
  17. products,
  18. // 成功操作
  19. () => commit(tyeps.CHECKOUT_SUCCESS),
  20. // 失败操作
  21. () => commit(types.CHECKOUT_FAILURE, savedCartItems)
  22. )
  23. }
  24. }

aciton 通过 store.dispacth 方法触发

  1. store.dispatch('increment')
  2. // 同事 actions 支持载荷的方式和对象的方式分发
  3. // 载荷形式
  4. store.dispatch('increment',{
  5. amount: 10
  6. })
  7. // 对象形式分发
  8. store.dispatch({
  9. type: 'incrementAsync',
  10. amount: 10
  11. })

Aciton 处理异步任务

如果通过异步操作变更数据,必须通过 action ,不能直接 使用 mutation,但是在 action 中还是要通过触发同步 mutation 的方式 间接变更数据。

store中定义actions

  1. // store/index.js
  2. const store = new Vuex.Store({
  3. state:{
  4. count: 0
  5. }
  6. mutation: {
  7. add (state){
  8. state.count++
  9. }
  10. },
  11. action: {
  12. addAsync({commit}){
  13. setTimeout(()=>{
  14. commit('add')
  15. }, 1000)
  16. }
  17. }
  18. })

在组件中分发 actions

  1. // 组件中
  2. import { mapState, mapMutations, mapActions } from 'vuex'
  3. methods: {
  4. // 方法1. 借助 mapActions 辅助函数
  5. ...mapActions(['subtractAsync']),
  6. // 方法2. 通过dispatch
  7. handleBtn2(amount) {
  8. this.$store.dispatch('addAsync', { amount })
  9. }
  10. },

组合 actions

store.dispath 可以处理被触发的 aciton 的处理函数返回的 Promise,并且 store.dispatch 仍然返回 promise

  1. actions:{
  2. actionA({commit}){
  3. return new Promise((resolve, reject)=>{
  4. setTimeout(()=>{
  5. commit('someMutation')
  6. resolve()
  7. }, 1000)
  8. })
  9. }
  10. }
  1. store.dispatch('actionA').then(()=>{})
  1. actions:{
  2. actionB({dispatch,commit}){
  3. return dispatch('actionA').then(()=>{
  4. commit('someMutation')
  5. })
  6. }
  7. }
  8. // async/await 写法
  9. actions:{
  10. async actionA({commit}){
  11. commit('gotData', await getData())
  12. },
  13. async actionB({dispatch, commit}){
  14. await dispatch('actionA') // 等待 actionA 完成
  15. commit('gotOtherData', await getOtherData())
  16. }
  17. }

一个 store.dispatch 在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。