概念

在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 Vue 应用中多个组件的共享状态进行集中式的管理(读 / 写),也是一种组件间通信的方式,且适用于任意组件间通信

主要用于多个组件共享数据

搭建vuex环境

  • 创建文件:src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 引入 Vue 核心库
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
// 应用 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 配置项
1
2
3
4
5
6
7
8
9
10
11
// ......
// 引入store
import store from './store'
// ......

// 创建 vm
new Vue({
el: '#app',
render: h => h(App),
store
})

基本使用

  • 初始化数据,配置 actions,配置 mutations,操作文件 store.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 引入 Vue 核心库
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
// 引用 Vuex
Vue.use(Vuex)

const actions = {
// 响应组件中加的动作
jia(context,value) {
// console.log('actions中的jia被调用了', miniStore, value)
context.commit('JIA',value)
}
}

const mutations = {
// 执行加
JIA(state,value) {
// console.log('mutations中的JIA被调用了', 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('action中的方法名',数据) 或 $store.commit('mutations中的方法名',数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过 actions,即不写 dispatch,直接编写 commit

getters的使用

  1. 当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工
  2. store.js 中追加 getters 配置
  3. 组件中读取数据:$store.getters.bigSum
1
2
3
4
5
6
7
8
9
10
11
12
// ......
const getters = {
bigSum(state) {
return state.sum * 10
}
}

// 创建并暴露 store
export default new Vuex.Store({
// ......
getters
})

四个map方法的使用

导入

1
import {mapState, mapGetters, mapActions, mapMutations} from 'vuex'

mapState

用于帮助我们映射 state 中的数据为计算属性

1
2
3
4
5
6
7
computed: {
// 借助 mapState 生成计算属性:sum,school,subject(对象写法)
...mapState({sum:'sum', school:'school', subject:'subject'}),

// 借助 mapState 生成计算属性:sum,school,subject(数组写法)
...mapState(['sum', 'school', 'subject'])
}

mapGetters

用于帮助我们映射 getters 中的数据为计算属性

1
2
3
4
5
6
7
computed: {
// 借助 mapGetters 生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'}),

// 借助 mapGetters 生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
}

mapActions

用于帮助我们生成与 actions 对话的方法,即:包含 $store.dispatch(xxx) 的函数

1
2
3
4
5
6
7
methods: {
// 靠 mapActions 生成:incrementOdd,incrementWait(对象形式)
...mapActions({incrementOdd:'jiaOdd', incrementWait:'jiaWait'}),

// 靠 mapActions 生成:incrementOdd,incrementWait(数组形式)
...mapActions(['jiaOdd', 'jiaWait'])
}

mapMutations

用于帮助我们生成与 mutations 对话的方法,即:包含 $store.commit(xxx) 的函数

1
2
3
4
5
6
7
methods: {
// 靠 mapActions 生成:increment,decrement(对象形式)
...mapMutations({increment:'JIA',decrement:'JIAN'}),

// 靠 mapMutations 生成:JIA,JIAN(对象形式)
...mapMutations(['JIA','JIAN'])
}

备注:mapActions 与 mapMutations 使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则传的参数是事件对象 event

模块化+命名空间

在 Vuex 中,使用 namespaced: true 可以启用模块命名空间功能。启用后,模块的所有内容(如 state、mutations、actions、getters)都将被封装在该模块的命名空间内。这样可以有效避免不同模块内部的命名冲突,并提供更好的代码组织和可维护性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const countAbout = {
namespaced: true,
state: {
// ...
},
mutations: {
// ...
},
actions: {
// ...
},
getters: {
// ...
}
}

const store = new Vuex.Store({
modules: {
moduleA
}
});
  • 开启命名空间后,组件中读取 state 数据:
1
2
3
4
// 方式一:自己直接读取
this.$store.state.countAbout.list
// 方式二:借助 mapState 读取:用 mapState 取 countAbout 中的 state 必须加上 'countAbout'
...mapState('countAbout',['sum','school','subject'])
  • 开启命名空间后,组件中读取 getters 数据:
1
2
3
4
// 方式一:自己直接 dispatch
this.$store.dispatch('countAbout/jiaOdd', 666)
// 方式二:借助 mapActions:
...mapActions('countAbout', { incrementOdd: 'jiaOdd',incrementWait: 'jiaWait' })
  • 开启命名空间后,组件中调用 commit
1
2
3
4
// 方式一:自己直接 commit
this.$store.commit('personAbout/ADD_PERSON',person)
// 方式二:借助 mapMutations:
...mapMutations('countAbout',{ increment: 'JIA',decrement: 'JIAN' }),