vuex是专门在vue中实现集中状态(数据)管理的一个vue插件,对vue应用中的多个组件的共享状态进行集中式管理,也是一种组件之间通信的方式,且适用于任意组件间的通信。
- 多个组件依赖于同一状态
- 来自不同组件的行为需要变更同一状态
一、搭建环境
- 创建文件:
src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
// 准备actions对象——响应组件中用户的动作
const actions = {}
// 准备mutations对象——修改state中的数据
const mutations = {}
// 准备state对象——保存具体的数据
const state = {}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
- 在
main.js
中创建vm时传入store
配置项
// 引入store
import store from './store/index'
// 创建vm
new Vue({
el: '#app',
render: h => h(App),
store,
beforeCreate() {
Vue.prototype.$bus = this;
}
})
二、基本使用
- 初始化数据、配置
actions
、配置mutations
、操作文件store.js
src/store/index.js:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const actions = {
add(context, value) {
context.commit('ADD', value);
}
}
// 为了区分,actions中小写,mutations中大写
const mutations = {
ADD(state, value) {
state.sum += value;
}
}
// 初始化数据
const state = {
sum: 0
}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
- 组件中读取Vuex中的数据:
$store.state.sum
- 组件中修改vuex中的数据:
$store.dispatch('actions中的方法名', '数据')
或$store.commit('mutations中的方法名', 数据)
其中,如果没有网络请求或者其他业务逻辑,组件中也可以越过actions,即不写dispatch
,直接编写
commit
三、getters的使用
- 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
- 在store.js中追加getters配置:
const getters = {
bigSum(state) {
return state.num * 10;
}
}
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
- 组件中读取数据:
$store.getters.bigNum
四、mapState、mapGetters
mapState方法:用于帮助我们映射state
中的数据为计算属性
mapGetters方法:用宇帮助我们映射getters
中的数据为计算属性
在模板中需要使用$store.state.num
进行展示,为了不在模板中写这么复杂,可以在计算属性中使用如下方法,在模板中使用sum
进行展示:
computed: {
sum() {
return this.$store.state.num;
}
}
更简单的方法是引入mapState
:
import {mapState, mapGetters} from 'vuex';
computed: {
// 方式一:借助mapState生成计算属性,从state中读取数据(对象方法)
...mapState({sum: 'sum', school: 'school'}),
// 方式二:借助mapState生成计算属性,从state中读取数据(数组方法)
...mapState(['sum', 'school'])
}
五、mapActions、mapMutations
mapActions方法:用于帮助我们生成与actions
对话的方法,即包含$store.dispatch(xxx)
的函数
mapMutations方法:用于帮助我们生成与mutations
对话的方法,即包含$store.commit(xxx)
的函数
mapActions与mapMutations使用时,如果需要传递参数,需要在模板中绑定事件时传递好参数,否则参数是事件对象。
原来:
<button @click="increment">xxx</button>
<button @click="decrement">xxx</button>
methods: {
increment() {
this.$store.commit('ADD', this.n);
},
decrement() {
this.$store.commit('JIAN', this.n);
}
}
使用mapMutations:
<button @click="increment(n)">xxx</button>
<button @click="decrement(n)">xxx</button>
methods: {
// 借助mapMutations生成对用的方法,方法中调用commit方法去联系mutations
...mapMutations({increment: 'ADD', decrement: 'JIAN'})
}
六、vuex模块化+namaspace
目的:让代码更好维护,让多种数据分类更加明确。
scr/store/index.js:
// 求和相关的配置
const countOptions = {
namespaced: true,
actions: {},
mutations: {},
state: {},
getters: {}
}
// 人员管理相关的配置
const personOptions = {
namespaced: true,
actions: {},
mutations: {},
state: {},
getters: {}
}
export default new Vuex({
modules: {
countAbout: countOptions,
personAbout: personOptions
}
})
computed: {
...mapState('countAbout', ['sum', 'school']),
...mapState('personAbout', ['personList']),
...mapGetters('countAbout', ['bigSum'])
},
methods: {
...mapMutations('countAbout', {increment: 'ADD', decrement: 'JIAN'}),
...mapActions('countAbout', {........})
}
如果不用简写:
computed: {
sum() {
return this.$store.state.countAbout.sum;
},
bigSum() {
return this.$store.getters['countAbout/bigSum'];
}
},
methods: {
this.$store.commit('countAbout/ADD', xxx);
this.$store.dispatch('countAbout/add', xxx);
}