一、Action用于处理异步任务
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation。但是在Action中还是要通过触发Mutation的方式间接变更数据。
只有mutation中定义的函数,才有权利去修改state中的数据,因此actions最终还是要调用mutation。
二、扩展:vue-devtools
有了vue-devtools我们可以直观的观察到组件和触发事件。下图为vue-devtools常用功能的简单介绍,下载教程:https://blog.csdn.net/weixin_43361722/article/details/116494776
现在我们来改动一下上节的计数器demo,体验一下Actions,看一下触发actions的两种方式。
仔细看state、mutation、actions,包括下节的getters的定义及触发有很多相似之处。
三、触发actions的两种方式
- 改动store/index.js——定义actions
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
add (state) {
state.count++
},
addN (state, step) {
setTimeout(() => {
state.count += step
}, 1000)
},
sub (state) {
state.count--
},
subN (state, step) {
state.count -= step
}
},
// -------------------------------新增actions处理异步
actions: {
// context是和store对象具有相同方法和属性的对象
addAsync (context) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据;
// 必须通过 contex.commit() 触发某个 mutation 才行;
context.commit('add')
}, 1000)
},
// 异步也是可以传参的,这里的step为我们的形参
addNAsync (context, step) {
setTimeout(() => {
context.commit('addN', step)
}, 1000)
},
subAsync (context) {
setTimeout(() => {
context.commit('sub')
}, 1000)
},
subNAsync (context, step) {
setTimeout(() => {
context.commit('subN', step)
}, 1000)
}
}
// -------------------------------
})
- 改动Addition组件——实践第一种方式:
$store.dispatch
触发actions
<template>
<div>
<p>当前count的值为:{{ $store.state.count}}</p>
<button @click="handleAdd()">+1</button>
<button @click="handleAddN()">+N</button>
<!-- 这里的 dispatch 函数专门来触发 actions -->
<!-- 这节调用方式没有再写methods -->
<button @click="$store.dispatch('addAsync')">+1 Async</button>
<button @click="$store.dispatch('addNAsync', 5)">+N Async</button>
<!-- ---------------------------------- -->
</div>
</template>
<script>
export default {
data () {
return {}
},
methods: {
handleAdd () {
this.$store.commit('add')
},
handleAddN () {
this.$store.commit('addN', 3)
}
}
}
</script>
- 改动Subtraction组件——实践第二种方式:
mapActions
触发actions
<template>
<div>
<p>当前count的值为:{{ count }}</p>
<button @click="handleSub()">-1</button>
<button @click="handleSubN()">-N</button>
<!-- 3.已经映射为methods函数可以直接调用无须再写handle函数 -->
<button @click="subAsync()">-1 Async</button>
<button @click="subNAsync(5)">-N Async</button>
</div>
</template>
<script>
// 1.从vuex中按需导入mapActions
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count'])
},
methods: {
...mapMutations(['sub', 'subN']),
// 2. 将指定的actions函数,映射为当前组件的methos函数
...mapActions(['subAsync', 'subNAsync']),
handleSub () {
this.sub()
},
handleSubN () {
this.subN(3)
}
}
}
</script>