六、Vuex状态管理机
1.介绍
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
应用场景:
同级别组件之间通讯
let comA = {}
let comB = {}
2.基本使用:
1)state(类似于vue实例中data)
存储数据的地方,将每个vue实例中的公共变量抽取出来进行统一管理
state: {
msg: 'hello vuex'
}
在vue中,通过计算属性获取存储在vuex的状态,可以直接获取,也可以通过辅助函数获取
computed: {
count() {
return this.$store.state.count
}
// 或者
...Vuex.mapState(["count"])
}
2)getters(类似于vue实例中的computed)
用于将state中静态的数据经过计算再返回
getter: {
reMsg(state) {
return state.msg.toUpperCase()
}
}
在vue中,可以通过计算属性访问
computed: {
reMsg() {
return this.$store.getters.reMsg
}
// 或者
...Vuex.mapGetters(["reMsg"])
}
3)mutations(突变)
更改Vuex的store中的状态的唯一方法是提交 mutation,必须是同步操作。
mutation函数的第一个参数为state ,第二个参数是来接受在调用mutation的时候用户传递的实参
mutations: {
SET_MSG(state, payload) {
state.msg = payload
}
}
可以在vue生命周期钩子中提交突变或者在methods中映射突变方法
created() {
// 参数一是突变方法的名字,参数二是传递的实参
this.$store.commit('SET_MSG', 'hello mutation')
}
methods:{
...Vuex.mapMutations(['SET_MSG'])
}
4)actions(动作)
用来存放异步请求方法,action提交的是 mutation,从而间接的变更state中的状态
actions中的异步请求接受一个形参-context(上下文对象)
可使用context.state获取state
可使用context.getters获取getters
可使用context.commit()提交突变
可使用context.dispatch()分发动作
actions: {
async findAll(context) {
let res = await axios.get('http://...');
// 提交突变
context.commit('SET_MSG', res.data.data)
}
}
可以在vue生命周期钩子中分发动作或者在methods中映射actions中的方法
created() {
// 参数一是异步函数的名字,参数二可以传递实参
this.$store.dispatch('findAll')
}
methods:{
...Vuex.mapActions(['findAll'])
}
5)案例-定义状态机实例
let store = new Vuex.Store({
state: {
msg: 'hello vuex'
},
getters: {
reMsg(state) {
return state.msg.toUpperCase()
}
},
// 突变
mutations: {
SET_MSG(state, payload) {
state.msg = payload
}
},
// 动作
actions: {
async findAll(context) {
let res = await axios.get('http://');
// 提交突变
context.commit('SET_MSG', res.data.data)
}
}
})
6)通过store将状态机实例注入进去
let vm = new Vue({
el: '#app',
store
})
3.辅助函数
Vuex构造函数内部提供了快捷映射数据、方法的方法
使用对象的解构,将内部的辅助函数解构出来
let { mapState, mapGetters, mapMutations, mapActions } = Vuex
使用
computed: {
...mapState(['msg']), // 状态映射
...mapGetters(['reMsg']) // 计算属性映射
},
methods: {
...mapMutations(['SET_MSG']), // 突变映射
...mapActions(['findAll']) // 动作映射
}
4.模块化开发
1)目的
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。
当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。
每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
namespaced表示设置命名空间
2)使用
let moduleA = {
namespaced: true,
state() {
return {}
},
getters: {},
mutations: {},
actions: {}
}
let moduleB = {
namespaced: true,
state() {
return {}
},
getters: {},
mutations: {},
actions: {}
}
let store = new Vuex.Store({
modules: {
// 给状态机模块重命名
a: moduleA,
b: moduleB
}
})
let vm = new Vue({
el: '#app',
data: {},
computed: {
// 映射状态,第一个参数是模块的名字
...mapState('a',['aData']),
...mapState('b',['bData']),
// 映射计算属性,第一个参数是模块的名字
...mapGetters('a',['reAData']),
...mapGetters('b',['reBData']),
},
methods: {
// 映射突变
...mapMutations('a', ['SET_ADATA']),
...mapMutations('b', ['SET_BDATA']),
// 映射动作
...mapActions('a', ['findAll])
...mapActions('b', ['query])
},
created(){
this.findAll() // 调用/执行方法
},
store: store
})