Vuex之Action

Action于Mutation不同的是
- Action可以提交任意异步操作,Mutation只能提交同步操作。
- Action提交的是mutation,而不是直接变更状态
为什么已经有了mutation还要有action呢!原因就是异步操作哈!想同步就同步,想异步就异步,但是,Action通常是异步的哈!

1.注册

下面是一个简单的action的注册

const store=new Vuex.Store({
 state:{
  count:0
 },
 mutations:{
  increment(state){
   state.count++
  }
 },
 actions:{
  increment(context){
   context.commit('increment')
  }
 }
})

Action函数接受一个与store函数具有相同方法和属性的context对象,所以可以调用context.commit提交一个mutation,或者通过context.statecontext.getters获取state和getters。

2.异步注册

actions:{
 incrementAsync({ commit }){   //这里的{ commit }运用了解构赋值,触发时传入commit对应的参数
  setTimeout(()=>{
   commit('increment')
  },1000)
 }
}

分发Action

Action是怎么触发的呢?store.dispatch('increment')

1.在store.js中分发
Action的分发和Mutation一样支持载荷方式和对象方式。

//以载荷方式
store.dispatch('incrementAsync',{
 amount:10
})

//以对象方式分发
store.dispatch({
 type:'imcrementAsync',
 amount:10
})

2.在组件中分发
Action的分发在组件中使用this.$store.dispatch(‘XXX’)。也可以使用mapActions辅助函数。需要在根节点注入store。(mutation是使用mapMutations)

import { mapActions } from 'vuex'
export default{
 methods:{
  ...mapActions([
   'increment',     // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
   'incrementBy'   // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
  ]),
  ...mapActions({
   add:'increment'   // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
  })
 }
}

购物策划实例

actions:{
 checkout({ commit,state },products){
  const savedCartItems=[..state.cart.added]    //保存购物车的物品
  commit(type.CHECKOUT_REQUEST)    //发出结账请求,然后清空购物车
  shop.buyProducts(
   products,
   //成功操作
   () => commit(types.CHECKOUT_SUCCESS)//action产生的副作用即状态变更
   //失败操作
   () => commit(types.CHECKOUT_FAILURE,saveCartItems)
  )

 }
}

组合Action

为什么要组合Action?因为要处理更加复杂的异步流程
了解如何组合之前我们有必要了解一些垫底的知识。首先,store.dispatch可以处理被触发的action的处理函数返回的Promise,并且store.dispatch仍然返回Promise。那么我们可以在action里返回Promise

actions:{
 actionA({ commit }){  //处理函数actionA返回Promise
   return new Promise((resolve,reject) => {
    setTimeout(() => {
     commit('someMutation')
     resolve()
    },1000)
   })
 }
}


store.dispath('actionA').then(() => {
 //....
})

另外一个action

actions:{
 actionB({ dispatch,commit }){
  return dispatch('actionA').then(() => {
   commit('someOtherMutation')
  })
 }
}

最后,我们使用async/await组合action:

actions:{
 async actionA({ commit }){
  commit('gotData', await getData())
 },
 async actionB({ dispatch,commit }){
  await dispatch('actionA')             //等待actionA完成
  commit('gotOtherData',await getOtherData())
 }
}

猜你喜欢

转载自blog.csdn.net/e_li_na/article/details/80256096