前言
为什么引入actions ? 不是已经有@click点击后commit()mutations吗?
actions是为了异步操作正常进行,方便使用浏览器的插件,即Vue插件去监控异步操作的执行真正时序。
因为,你不使用actions去执行异步,他并不会按照预想完成异步,比如,
//index.js
mutations: {
update(state) {
setTimeout(()=>{
state.name = 'new data';}, 10000)
}
}
//app.vue
methods: {
btnUpdate() {
this.$store.commit( 'update' );
}
}
如果点击了btn,那么在F12,Vue中不会在10s后同时接收到Commit与数据改动的操作,而是点击后立即发出Commit操作,10s后才发生数据改变,因为在这里的commit是立即触发。
就是因为,这种commit与实际异步操作的不理想,所以就把异步操作写在actions里面,实现commit与异步操作是同时异步的。
二、actions基本使用
类似于mutations,actions也有[行为名](context, payload){ };
context就是$store对象,payload是传进来的参数,参数过多时,直接把参数打包成一个对象传给payload
//index.js
actions:{
asyncUpdate(context, payload){
setTimeout( ()=>{
context.commit('update')},10000);
}
}
//app.vue
methods:{
btnUpdate(){
this.$store.dispath('asyncUpdate',{
params })
}
}
高级使用:
如果,想在commit完成后,做出一些动作,来告诉其他组件,这个异步操作已经完成,那么怎么实现?
思路:
利用payload中参数,以函数作为参数并传给payload,在执行玩commit后,就做出动作提示,修改或打印payload里面的参数,即:
//index.js
actions:{
asyncUpdate(context, payload){
setTimeout( ()=>{
context.commit('update');
console.log(payload.message);
payload.success();
},10000);
}
}
//payload in app.vue
payload ={
message :'have finished !',
success: ()=>{
console.log('success!') }
}
引入Promise的异步actions使用:
因为,你在commit后面写的代码,如果太多,就很臃肿,此时若引入Promise进行封装,那么代码可以更加丝滑。
在actions异步操作里,用Promise的前提是,这个dispatch()函数,只是个代理,底层是大概是这么写的
dispatch(' actionsFunc ', payload ) { return actionsFunc(payload); }
即,代理执行了actionsFunc,那么dispatch()最终的返回值,还是actionsFunc的返回值;
于是,上面的代码可以写成:
//index.js
actions:{
asyncUpdate(context, payload){
return New Promise((resolve, reject)=>{
setTimeout( ()=>{
context.commit('update');
resolve('sb');
},10000);
}
}
}
//app.vue
methods:{
btnUpdate(){
this.$store.dispatch('asyncUpdate',
{
message :'have finished !',
success: ()=>{
console.log('success!') }
}).then(res=>{
//异步操作完成后的提示,写在这里
console.log(payload.message);
console.log(res);//sb
});
}
}
//payload in app.vue
payload ={
message :'have finished !',
success: ()=>{
console.log('success!') }
}