Vuex 状态管理
一种组件间通信的方式, 适用于任意组件间通信
概述
专门在Vue中实现集中式状态、数据管理的一个Vue插件, 对Vue应用中多个组件的共享状态进行集中式的管理: 读、写
源码地址: https://github.com/vuejs/vuex
- 示例图:

Vuex 使用时机
- 多个组件依赖同一状态
- 来自不同组件的行为需要变更同一状态
Vuex 工作原理
Vuex分为三部分:
Actions: 用来处理异步回调获取数据的模块, 如调用后端API, 如果没有异步操作可跳过Actions直接调用Mutations中的方法处理数据Mutations: 用来处理State中数据的模块State: 用来存储数据的模块, 类型组件中的data属性
- 示意图

环境搭建
第一步: 安装
- 安装
Vuex:
npm i vuex第二步: 应用Vuex并创建store
需要在
Vue.use(Vuex)应用Vuex之后才能创建store实例, 且模块化会将import语句提前, 所有没有在main.js中应用Vuex在
src目录新建store文件夹, 并在文件夹中新建index.js文件index.js代码示例
// 引入 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中将store挂载到Vue中
- 代码示例
import store from './store'
new Vue({
el: '#app',
store
})注意
应用Vuex与创建store实例的顺序问题, 不用在main.js中应用Vuex, 因为import的store会先执行
Vuex 基本使用
组件中读取Vuex中的数据:
$store.state.value
组件中修改Vuex中的数据:
$store.dispatch('actions中的方法名', 参数数据)$store.commit('mutations中的方法名', 参数数据)
若没有网络请求或其他业务逻辑, 组件中可以越过actions, 直接使用commit调用mutations中的方法
- 组件中示例代码:
export default {
data: {
n: 1
},
methods: {
add() {
this.$store.commit('addNormal', this.n)
},
addByWait() {
this.$store.dispatch('addWait', this.n)
}
}
}store中示例代码:
// 创建并导出 store
export default new Store({
actions: {
// 响应动作调用操作 mutations 中的事件
addWait() {
setTimeout(() => {
context.commit('addNormal', value)
}, 1000)
}
},
mutations: {
// 执行事件
addNormal(state, value) {
state.sum =+ value
}
},
state: {
sum: 0
}
})Getters
概念: 用来加工state中的数据, 相似于组件中的computed计算属性, 当state中的数据需要加工时使用
- 在
store中配置getters:
export default new Store({
getters: {
bigSum(state) {
return state.sum * 10
}
}
})- 组件中读取数据
<template>
<h1> 当前求和X10为:{{ $store.getters.bigSum }} </h1>
</template>Vuex 中 Map 方法的使用
注意
使用以下map方法需要先在组件中引入: import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
mapState 方法
用于映射state中的数据为计算属性, 共有两种写法:
- 对象写法:
{key: value}形式,key和value一致或不一致时都可使用, 页面中使用key获取数据 - 数组写法:
['xxx', 'yyy'], 数组中的元素要与state中的属性名一致, 页面中使用数组中元素获取数据
- 代码示例:
computed: {
// 对象写法
...mapState({getName: 'name', getAge: 'age'})
// 数组写法
...mapState(['name', 'age'])
}mapGetters 方法
用于映射getters中的数据为计算属性, 共有两种写法:
- 对象写法: 与上述
mapState方法一致 - 数组写法: 与上述
mapState方法一致
- 代码示例:
computed: {
// 对象写法
...mapGetters({newName: 'name', newAge: 'age'})
// 数组写法
...mapGetters(['name', 'age'])
}mapActions 方法
用于生成与actions对话的方法, 即包含$store.dispatch(xxx)的函数, 共有两种写法:
- 对象写法:
{key: value}形式,key和value一致或不一致时都可使用, 其中key用于页面中的绑定事件处理函数 - 数组写法:
['xxx', 'yyy'], 数组中的元素要与state中的属性名一致, 数组中元素用于页面中的绑定事件处理函数
- 代码示例:
methods: {
// 对象写法
...mapActions({getName: 'getUserName', getAge: 'getUserAge'})
// 数组写法
...mapActions(['getName', 'getAge'])
}注意
如需传参要在页面绑定事件时传递参数, 如<button @click="getName(xxx)">获取名字</button>, 否则参数是默认的事件对象$event
mapMutations
用于生成与mutations对话的方法, 即包含$store.commit(xxx)的函数, 共有两种写法:
- 对象写法: 与上述
mapActions方法一致 - 数组写法: 与上述
mapActions方法一致
传参: 与上述mapActions方法一致
- 代码示例:
methods: {
// 对象写法
...mapMutations({update: 'handleUpdate', del: 'handleDel'})
// 数组写法
...mapMutations(['update', 'del'])
}Vuex 模块化
目的: 让代码更好维护, 让多种数据分类更加明确
模块化使用步骤
- 在
store文件夹新建modules文件夹 - 在
modules文件夹中新建不同模块的.js文件 - 在
.js文件中分别配置actions、mutations和state等并导出模块, 需要开启命名空间:namespaced: true - 在
store/index.js文件中分别引入模块, 并配置到modules对象中
- 代码示例:
// store/modules/count.js 文件
export default {
namespaced: true,
actions: {
addWait(context, value) {
setTimeout(() => {
context.commit('ADD', value)
}, 1000)
}
},
mutations: {
ADD(state, value) {
state.sum += value
}
},
state: {
sum: 0
},
getters: {
bigSum(state) {
return state.sum * 10
}
}
}
// store/index.js 文件
import Vue from 'vue'
import Vuex from 'vuex'
import count from './modules/count.js'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
// count: count
count
}
})使用不同模块中的方法
- 组件中获取模块
count中state的数据
computed: {
// 直接获取
sum() {
return this.$store.state.count.sum
}
// 使用 mapState 获取
...mapState('count', ['sum'])
}- 组件中获取模块
count中getters的数据
computed: {
// 直接获取
bigSum() {
return this.$state.getters('count/bigSum')
}
// 使用 mapGetters 获取
...mapGetters('count', [' '])
}- 组件中调用模块
count中actions的方法
methods: {
// 直接调用
handleAddWait() {
this.$store.dispatch('count/addWait')
}
// 使用 mapActions 调用
...mapActions('count', { handleAddWait: 'addWait' })
}- 组件中调用模块
count中mutations的方法
methods: {
// 直接调用
handleAdd() {
this.$store.commit('count/ADD')
}
// 使用 mapMutations 调用
...mapMutations('count', { handleAdd: 'ADD' })
}