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.state
和context.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())
}
}