Action | Vuex
文章推薦指數: 80 %
store.dispatch('xxx') 分发action,或者使用 mapActions 辅助函数将组件的methods 映射为 store.dispatch 调用(需要先在根节点注入 store ):.
指南API参考更新记录v4.xv3.x选择语言English简体中文日本語PortuguêsGitHub介绍Vuex是什么?安装开始核心概念StateGetterMutationAction分发Action在组件中分发Action组合ActionModule进阶项目结构组合式API插件严格模式表单处理测试热重载TypeScript支持迁移指南从3.x迁移到4.0Action#在Scrimba上尝试这节课Action类似于mutation,不同在于:Action提交的是mutation,而不是直接变更状态。
Action可以包含任意异步操作。
让我们来注册一个简单的action:conststore=createStore({
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。
当我们在之后介绍到Modules时,你就知道context对象为什么不是store实例本身了。
实践中,我们会经常用到ES2015的参数解构来简化代码(特别是我们需要调用commit很多次的时候):actions:{
increment({commit}){
commit('increment')
}
}
分发Action#Action通过store.dispatch方法触发:store.dispatch('increment')
乍一眼看上去感觉多此一举,我们直接分发mutation岂不更方便?实际上并非如此,还记得mutation必须同步执行这个限制么?Action就不受约束!我们可以在action内部执行异步操作:actions:{
incrementAsync({commit}){
setTimeout(()=>{
commit('increment')
},1000)
}
}
Actions支持同样的载荷方式和对象方式进行分发://以载荷形式分发
store.dispatch('incrementAsync',{
amount:10
})
//以对象形式分发
store.dispatch({
type:'incrementAsync',
amount:10
})
来看一个更加实际的购物车示例,涉及到调用异步API和分发多重mutation:actions:{
checkout({commit,state},products){
//把当前购物车的物品备份起来
constsavedCartItems=[...state.cart.added]
//发出结账请求,然后乐观地清空购物车
commit(types.CHECKOUT_REQUEST)
//购物API接受一个成功回调和一个失败回调
shop.buyProducts(
products,
//成功操作
()=>commit(types.CHECKOUT_SUCCESS),
//失败操作
()=>commit(types.CHECKOUT_FAILURE,savedCartItems)
)
}
}
注意我们正在进行一系列的异步操作,并且通过提交mutation来记录action产生的副作用(即状态变更)。
在组件中分发Action#你在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件的methods映射为store.dispatch调用(需要先在根节点注入store):import{mapActions}from'vuex'
exportdefault{
//...
methods:{
...mapActions([
'increment',//将`this.increment()`映射为`this.$store.dispatch('increment')`
//`mapActions`也支持载荷:
'incrementBy'//将`this.incrementBy(amount)`映射为`this.$store.dispatch('incrementBy',amount)`
]),
...mapActions({
add:'increment'//将`this.add()`映射为`this.$store.dispatch('increment')`
})
}
}
组合Action#Action通常是异步的,那么如何知道action什么时候结束呢?更重要的是,我们如何才能组合多个action,以处理更加复杂的异步流程?首先,你需要明白store.dispatch可以处理被触发的action的处理函数返回的Promise,并且store.dispatch仍旧返回Promise:actions:{
actionA({commit}){
returnnewPromise((resolve,reject)=>{
setTimeout(()=>{
commit('someMutation')
resolve()
},1000)
})
}
}
现在你可以:store.dispatch('actionA').then(()=>{
//...
})
在另外一个action中也可以:actions:{
//...
actionB({dispatch,commit}){
returndispatch('actionA').then(()=>{
commit('someOtherMutation')
})
}
}
最后,如果我们利用async/await,我们可以如下组合action://假设getData()和getOtherData()返回的是Promise
actions:{
asyncactionA({commit}){
commit('gotData',awaitgetData())
},
asyncactionB({dispatch,commit}){
awaitdispatch('actionA')//等待actionA完成
commit('gotOtherData',awaitgetOtherData())
}
}
一个store.dispatch在不同模块中可以触发多个action函数。
在这种情况下,只有当所有触发函数完成后,返回的Promise才会执行。
MutationModule
延伸文章資訊
- 1Vuex showdown: Mutations vs. actions - LogRocket Blog
- 2Vuex 中的Getters 及mapGetters, mapActions | 六角學院
- 3About us - MapAction
- 4Vuex的使用(八)——actions和mapActions的用法 - CSDN博客
运行后点击mapActions按钮可以看到一秒后state发生了变化,这表示actions可以以异步的方式来调用mutations ...
- 5[Vue.js] Vuex 學習筆記(8) - actions 的核心概念
store.dispatch('xxx') 分發action,或者使用 mapActions 輔助函數將組件的methods 映射為 store.dispatch 調用。 import { ma...