Vuex 的主要核心概念:
new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
getters: {
}
})
一、State
State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储。
state: {
count:0
},
- 访问 State 中数据的第一种方式:
//this.$store.state.全局数据名称
- 访问 State 中数据的第二种方式:
// 1.从 vuex 中按需导入 mapState 函数
import {mapState} from 'vuex'
通过导入的 mapState 函数,将当前组件需要的全局数据,映射为当前组件的 computed 计算属性:
// 2.将全局数据,映射为当前组件的计算属性
computed:{
...mapState(['count'])
}
二、Mutation
Mutation 用于变更 Store 中的数据。
① 只能通过 Mutation 变更 Store 数据,不可以直接操作 Store 中的数据。
② 通过着这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
mutations: {
// 1.
add(state){
state.count++
}
// 2.传递参数 第一个参数永远为自身state 第二个为传参
//addN(state,step){
// state.count += step
//}
},
- 调用 mutations 的第一种方式:
methods:{
btn1(){
// 1.
this.$store.commit('add')
// 2. 传参
//this.$store.commit('addN',3)
}
}
- 调用 mutations 的第二种方式:
// 1.从 vuex 中按需导入 mapMutations 函数
import {mapMutations} from 'vuex'
通过导入的 mapMutations 函数,将需要的 mutations 函数,映射为当前组件的methods方法:
methods:{
...mapMutations(['sub','subN']),
btn2(){
// 1.
this.sub()
// 2.传参
//this.subN(3)
}
}
三、Action
Action 用于处理异步任务。
如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是要通过触发 Mutation 的方式间接变更数据。
actions: {
// 1.
addAsync(context){ // context代表当前Store
setTimeout(() => {
//在 actions 中,不能直接修改 state 中的数据
//必须通过 context.commit() 触发某个 mutation 才可以
context.commit('add')
}, 1000);
},
// 2.传参
addNAsync(context,step){
setTimeout(() => {
context.commit('addN',step)
}, 1000);
}
},
- 调用 actions 的第一种方式:
methods:{
btn1(){
// 1.
this.$store.dispatch('addAsync')
// 2.传参
this.$store.dispatch('addNAsync',5)
}
}
- 调用 actions 的第二种方式:
// 1.从 vuex 中按需导入 mapActions 函数
import {mapActions} from 'vuex'
通过导入的 mapActions 函数,将需要的 actions 函数,映射为当前组件的 methods方法:
methods:{
...mapActions(['subAsync','subNAsync']),
btn2(){
this.subAsync()
// this.subNAsync(3)
}
}
四、Getter
Getter 用于对 Store 中的数据进行加工处理形成新的数据。
① Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似 Vue 的计算属性。
② Store 中数据发生变化,Getter 的数据也会跟着变化。
- 使用 getters 的第一种方式:
this.$store.getters.名称
- 使用 getters 的第二种方式:
// 1.从 vuex 中按需导入 mapGetters 函数
import {mapGetters} from 'vuex'
// 2.将当前组件需要的 getter ,映射为当前组件的 computed 计算属性
computed:{
...mapGetters(['showNum'])
},
五、案例
计数器案例完整代码
store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0
},
mutations: {
// mutations函数中 不可执行异步操作
// 1.
add(state){
state.count++
},
// 2.传递参数 第一个参数永远为自身state 第二个为传参
addN(state,step){
state.count += step
},
sub(state){
state.count--
},
subN(state,step){
state.count -= step
}
},
actions: {
addAsync(context){
setTimeout(() => {
context.commit('add')
}, 1000);
},
// 传参
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);
}
},
getters:{
showNum(state){
return '当前最新的数量为:'+state.count
}
}
})
Addition.vue
<template>
<div>
<!-- 访问 State 中数据的第一种方式:(this)可略.$store.state.全局数据名称 -->
<!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
<!-- 使用 getters 的第一种方式 -->
<h3>{{$store.getters.showNum}}</h3>
<button @click="btn1">+1</button>
</div>
</template>
<script>
export default {
data(){
return{};
},
methods:{
btn1(){
// 触发 mutations 的第一种方式
// 1.
this.$store.commit('add')
// 2. 传参
//this.$store.commit('addN',1)
// 异步
// 触发 actions 的第一种方式
// 1.
// this.$store.dispatch('addAsync')
// 2.传参
// this.$store.dispatch('addNAsync',5)
}
}
}
</script>
Subtraction.vue
<template>
<div>
<!-- <h3>当前最新的count值为:{{count}}</h3> -->
<h3>{{showNum}}</h3>
<button @click="btn2">-1</button>
<!-- <button @click="subAsync">-1 Async</button> -->
</div>
</template>
<script>
// 访问 State 中数据的第二种方式:
import {mapState} from 'vuex'
// 触发 mutations 的第二种方式
import {mapMutations} from 'vuex'
// 触发 actions 的第二种方式
import {mapActions} from 'vuex'
// 使用 getter 的第二种方式
import {mapGetters} from 'vuex'
export default {
data(){
return{};
},
computed:{
...mapState(['count']),
...mapGetters(['showNum'])
},
methods:{
// ...mapMutations(['sub']),
...mapMutations(['sub','subN']),
// 异步
...mapActions(['subAsync','subNAsync']),
btn2(){
this.sub()
// this.subN(3)
//
// this.subAsync()
// this.subNAsync(3)
}
}
}
</script>
app.vue
<template>
<div>
<my-add></my-add>
<hr />
<my-sub></my-sub>
</div>
</template>
<script>
import Addition from './components/Addition.vue'
import Subtraction from './components/Subtraction.vue'
export default {
data() {
return {}
},
components: {
'my-add': Addition,
'my-sub': Subtraction,
},
}
</script>