actions类似于mutations
,不同在于:Action提交的是mutation,而不是直接变更状态;
Action可以包含任意异步操作,Action函数接受一个与store实例具有相同方法和属性的
context
对象,因此你可以调用
context.commit提交一个mutation,
或者通过
context.state 和context.getters来获取state和getters
。
Action 通过store.dispatch方法触发:store.dispatch(‘increment’)
在
store.js
中声明actions
actions是可以调用Mutations里的方法的:
// 4、actions异步修改状态
const actions = {
// addAction (context) {
// context.commit('add', 10)
// setTimeout(() => {
// context.commit('reduce')
// }, 5000)
// console.log('我比reduce先执行了')
// },
addAction ({commit}) {
commit('add', 10)
setTimeout(() => {
commit('reduce')
}, 3000)
console.log('我比reduce先执行了')
},
reduceAction ({commit}) {
commit('reduce')
}
}
在actions里写了两个方法addAction和reduceAction,在方法体里,都用commit调用了Mutations里边的方法。这两个方法传递的参数也不一样。
-
context
:上下文对象,这里你可以理解成store本身。
-
{commit}
:直接把commit对象传递过来,可以让方法体逻辑和代码更清晰明了。
模板中的使用
需要在count.vue模板中编写代码,让actions生效
(1)先复制两个以前有的按钮,并改成actions里的方法名,分别是:addAction和reduceAction。
<div>
<p>
<button @click="addAction">异步修改状态:+</button>
<button @click="reduceAction">异步修改状态:-</button>
</p>
</div>
(2)用import把mapActions引入
import {
mapState,
mapMutations,
mapActions
} from 'vuex'
(3)改造methods方法,用扩展运算符把mapMutations和mapActions加入
methods: {
...mapMutations(['add', 'reduce']),
...mapActions(['addAction', 'reduceAction'])
}
增加异步检验
现在看的效果和用Mutations作的一模一样,那actions有什么用,为了演示actions的异步功能,增加一个计时器(setTimeOut)延迟执行。在addAction里使用setTimeOut进行延迟执行。
const actions = {
addAction ({commit}) {
commit('add', 10)
setTimeout(() => {
commit('reduce')
console.log('action中执行mutations中的reduce方法')
}, 3000)
console.log('我比reduce先执行了')
},
reduceAction ({commit}) {
commit('reduce')
}
}
可以看到在控制台先打印出了‘我比reduce提前执行’,3s后再执行reduce操作