# vuex
# 1. 介绍
在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
# 2. 与全局事件总线的对比
全局事件总线(多组件共享数据):
vuex(多组件共享数据):
# 3. 何时使用?
多个组件需要共享数据时:
- 多个组件需要读取同一个数据
- 多个组件需要修改同一个数据
# 4. 原理图
# 5. 搭建 vuex 环境
# 5.1. 安装
# vue2.x 使用 vuex3
npm i vuex@3
# 5.2. 准备 store 对象
store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
// 创建 Vuex.Store 实例之前,必须先 Vue.use(Vuex)
Vue.use(Vuex);
// 准备 actions 对象 —— 响应组件中用户的动作
const actions = {}
// 准备 mutations 对象 —— 修改 state 中的数据
const mutations = {}
// 准备 state 对象 —— 保存具体的数据
const state = {}
// 创建 store
const store = new Vuex.Store({
actions,
mutations,
state
});
// 暴露 store
export default store;
注意:
- 创建
Vuex.Store
实例之前,必须先Vue.use(Vuex)
- webpack 优先执行
import xxx
语句,也就是说import
语句会置顶执行
# 5.3. 注册
main.js:
import Vue from 'vue';
import store from './store';
// Vue.use(vuex) 之后,所有的 vm、vc 都有 $store 属性
// 给当前 vm.options.store 赋值 store 后,
// 当前 vm 及其管理的所有 vc 都能通过 $store 访问到 store
new Vue({
// ...
store,
});
# 6. 基本使用
store = {
state: {
sum: 0
},
actions: {
// context = { dispatch commit getters state rootGetters rootState }
// 注意:
// actions 中一定要调用 commit 对 state 进行更改,
// 因为 devtools 是跟 mutations 打交道的
addWhenOdd({ state, commit }, param) {
if (state.sum % 2 === 1) {
commit('ADD', param);
}
}
},
mutations: {
ADD(state, param) {
state.sum += param;
}
}
}
# 6.1. 读
this.$store.state.xxx
# 6.2. 写
this.$store.dispatch('add', 2);
// 若没有网络请求或其他业务逻辑,组件中也可以越过 actions,而直接调用 mutations
this.$store.commit('ADD', 2);
# 7. getters
# 7.1. 概念
当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。
state 与 getters,可以类比 data 和 computed
# 7.2. 配置
store = {
state: {
sum: 0,
},
getters: {
bigSum(state) {
return state.sum * 10;
}
}
}
# 7.3. 读取
this.$store.getters.bigSum;
# 8. 四个 map 方法的使用
# 8.1. mapState
用于把 state 映射为 计算属性
mapState 的返回值是对象:
mapState({ mySum: 'sum', myStudentName: 'studentName' });
/*
{
myStudentName: ƒ mappedState()
mySum: ƒ mappedState()
}
*/
示例:
import { mapState } from 'vuex';
options = {
computed: {
// 繁琐写法
sum() {
return this.$store.state.sum;
},
// 数组写法: sum => this.$store.state.sum
...mapState([ 'sum', /* ... */ ]),
// 对象写法: sum => this.$store.state.sum
...mapState({ sum: 'sum', /* ... */ }),
// 对象写法: mySum => this.$store.state.sum
...mapState({ mySum: 'sum' }),
},
}
# 8.2. mapGetters
用于把 getters 映射为 计算属性
import { mapGetters } from 'vuex';
options = {
computed: {
bigSum() {
return this.$store.getters.bigSum;
},
...mapGetters([ 'bigSum' ]),
...mapGetters({ myBigSum: 'bigSum' }),
},
}
# 8.3. mapMutations
用于把 mutations 映射为 方法
注意:方法的第一个参数会当成 payload 传递过去
import { mapMutations } from 'vuex';
options = {
methods: {
add(num) {
this.$store.commit('ADD', num);
},
// 数组写法: ADD(num) => this.$store.commit('ADD', num);
...mapMutations(['ADD']),
// 对象写法: add(num) => this.$store.commit('ADD', num);
...mapMutations({ add: 'ADD' }),
},
}
# 8.4. mapActions
用于把 actions 映射为 方法
注意:方法的第一个参数会当成 payload 传递过去
import { mapActions } from 'vuex';
options = {
methods: {
addWhenOdd(num) {
this.$store.dispatch('addWhenOdd', num);
},
// 数组写法: addWhenOdd(num) => this.$store.dispatch('addWhenOdd', num);
...mapMutations(['addWhenOdd']),
// 对象写法: addWhenOdd(num) => this.$store.dispatch('addWhenOdd', num);
...mapMutations({ addWhenOdd: 'addWhenOdd' }),
}
# 9. modules
# 9.1. 目的
让代码更好维护,让多种数据分类更加明确。
# 9.2. 配置
修改store.js
const countAbout = {
namespaced: true,//开启命名空间
state:{ x: 1 },
mutations: { ... },
actions: { ... },
getters: {
bigSum(state){
return state.sum * 10
}
}
}
const personAbout = {
namespaced: true, //开启命名空间
state:{ ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
countAbout,
personAbout
}
})
# 9.3. 读取 state 数据
// 方式一:自己直接读取
this.$store.state.personAbout.list
// 方式二:借助 mapState 读取:
...mapState('countAbout',['sum','school','subject']),
# 9.4. 读取 getters 数据
// 方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
// 方式二:借助 mapGetters 读取:
...mapGetters('countAbout',['bigSum'])
# 9.5. 调用 dispatch
//方式一:自己直接 dispatch
this.$store.dispatch('personAbout/addPersonWang', person)
//方式二:借助mapActions:
...mapActions('countAbout', { incrementOdd: 'jiaOdd', incrementWait: 'jiaWait' })
# 9.6. 调用 commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON', person)
//方式二:借助mapMutations:
...mapMutations('countAbout', { increment:'JIA',decrement:'JIAN' })
上一篇: 下一篇:
本章目录