如果你之前使用过vue.js,咱们就能深刻体会在vue中各个组件之间传值的痛苦,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新。Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex的应用场景出现在Vue多个组件之间需要共享数据或状态。
Vuex有几个核心概念:State、Getter、Mutation、Action、Module。
State:存储状态数据 Getter:从状态数据派生数据,相当于State的计算属性。 Mutation:存储用于同步更改状态数据的方法,默认传入的参数为state。 Action:存储用于异步更改状态数据,但不是直接更改,而是通过触发Mutation方法实现,默认参数为context。 Module:Vuex模块化。
它们之间的交互关系如下图(来源于官方文档)所示:

通过一个案例快速理解vuex.
实现步骤如下:
1.创建Vuex.Store实例
在store目录下新建index.js,定义了一个counter属性,和getters.getAvgCounter属性。 注意:getters.getAvgCounter属性仅仅实现了counter属性的平均值,并没有真正改变其值。
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
counter: 100
},
getters: {
//获取平均值
getAvgCounter(state) {
return state.counter / 2;
}
}
});
export default store;
2.main.js文件中引入该文件
import Vue from 'vue'
import App from './App.vue'
import router from './router/router'
import store from './store/index'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
3.在vue视图组件中显示store中定义的数据
<template>
<div>
<p>
Welcome Page!<br>
在线人数是:{{$store.state.counter}}<br>
使用getter获取的在线人数平均值是:{{$store.getters.getAvgCounter}}<br>
</p>
</div>
</template>
<script>
export default {
name: "Welcome",
data(){
return{
}
}
}
</script>
<style scoped>
</style>
显示效果如下:

数据我们在页面是获取到了,但是如果我们需要修改counter值怎么办?如果需要修改store中的值唯一的方法就是提交mutation来修改。
4.在store中定义mutations
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
counter: 100
},
getters: {
//获取平均值
getAvgCounter(state) {
return state.counter / 2;
}
},
mutations: {
addCounter(state, value) {
console.log('in mutations->addCounter...');
state.counter += parseInt(value);
},
subCounter(state, value) {
console.log('in mutations->subCounter...');
state.counter -= parseInt(value);
}
}
});
export default store;
5.在vue视图组件添加两个按钮,调用mutations里的方法。
<template>
<div>
<p>
Welcome Page!<br>
在线人数是:{{$store.state.counter}}<br>
使用getter获取的在线人数平均值是:{{$store.getters.getAvgCounter}}<br>
<input type="text" v-model="addNum"/><input type="button" @click="addNumber" value="增加counter的值"><br>
<input type="text" v-model="subNum"/><input type="button" @click="subNumber" value="减少counter的值"><br>
</p>
</div>
</template>
<script>
export default {
name: "Welcome",
data(){
return{
addNum: 0,
subNum: 0
}
},
methods:{
addNumber(){
this.$store.commit('addCounter',this.addNum);
},
subNumber(){
this.$store.commit('subCounter',this.subNum);
}
}
}
</script>
<style scoped>
</style>
运行效果:

6.定义action 但是,官方并不推荐我们这样直接去修改store里面的值,而是让我们去提交一个actions,在actions中提交mutation再去修改状态值。修改store/index.js如下:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
counter: 100
},
getters: {
//获取平均值
getAvgCounter(state) {
return state.counter / 2;
}
},
mutations: {
addCounter(state, value) {
console.log('in mutations->addCounter...');
state.counter += parseInt(value);
},
subCounter(state, value) {
console.log('in mutations->subCounter...');
state.counter -= parseInt(value);
}
},
actions: {
actionAddCounter(context, value) {
context.commit("addCounter", value);
},
actionSubCounter(context,value){
context.commit("subCounter",value);
}
}
});
export default store;
7.在vue视图组件中调用action
<template>
<div>
<p>
Welcome Page!<br>
在线人数是:{{$store.state.counter}}<br>
使用getter获取的在线人数平均值是:{{$store.getters.getAvgCounter}}<br>
<input type="text" v-model="addNum"/><input type="button" @click="addNumber" value="增加counter的值"><br>
<input type="text" v-model="subNum"/><input type="button" @click="subNumber" value="减少counter的值"><br>
</p>
</div>
</template>
<script>
export default {
name: "Welcome",
data(){
return{
addNum: 0,
subNum: 0
}
},
methods:{
addNumber(){
this.$store.dispatch("actionAddCounter",this.addNum);
},
subNumber(){
this.$store.dispatch("actionSubCounter",this.subNum);
}
}
}
</script>
<style scoped>
</style>
运行效果与上面完全相同。
8.mutations与actions的区别
actions的特点:
mutations的特点: