Vuex中的Action
一、Action的基本定义
-
我们强调, 不要再Mutation中进行异步操作.
- 但是某些情况, 我们确实希望在Vuex中进行一些异步操作, 比如网络请求, 必然是异步的. 这个时候怎么处理呢?
- Action类似于Mutation, 但是是用来代替Mutation进行异步操作的.
- Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
-
Action的基本使用代码如下:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
asyncIncrement (context) {
context.commit('increment')
}
}
})
context
是什么?- Action 函数接受一个与
store
实例具有相同方法和属性的context
对象。 - 也就是说,你可以调用
context.commit
提交一个mutation
,或者通过context.state
和context.getters
来获取state
和getters
- Action 函数接受一个与
注意: context
和store
并不是同一个对象, 为什么呢? 我们后面学习Modules的时候, 再具体说.
二、Action的分发
- 在Vue组件中, 如果我们调用
action
中的方法, 那么就需要使用dispatch
methods: {
increment() {
this.$store.dispatch('asyncIncrement')
}
}
- Actions 支持同样的载荷(Payload)方式和对象方式进行分发:
methods: {
increment() {
// 以载荷形式分发
this.$store.dispatch('asyncIncrement', {
count: 10
})
// 以对象形式分发
this.$store.dispatch({
type: 'asyncIncrement',
count: 10
})
}
}
mutations: {
increment(state, payload) {
state.count += payload.count
}
},
actions: {
asyncIncrement(context, payload) {
setTimeout(() => {
context.commit('increment')
}, 1000);
}
}
三、Action返回的Promise
- Action 通常是异步的,那么如何知道 action 什么时候结束呢?更重要的是,我们如何才能组合多个 action,以处理更加复杂的异步流程?
- 首先,你需要明白
store.dispatch
可以处理被触发的action
的处理函数返回的Promise
,并且store.dispatch
仍旧返回Promise
,并且在成功或者失败后, 调用对应的resolve
或reject
.
actions: {
asyncIncrement(context, payload) {
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit('increment')
resolve()
}, 1000)
})
}
}
this.$store.dispatch('asyncIncrement').then(res => {
// ..
})
- 一个
store.dispatch
在不同模块中可以触发多个action
函数。在这种情况下,只有当所有触发函数完成后,返回的Promise
才会执行。
// 假设 getData() 和 getOtherData() 返回的是 Promise
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}