概述
- vuex 是 vue 的数据管理插件,可以管理 vue 通用的数据(多组件共享的数据),例如:购物车数据、个人信息数据
- 使用场景:
- 某个数据在多个组件中都被使用到(个人信息)
- 多个组件共同维护一份数据(购物车)
- 优点:
- 共同维护一份数据,数据集中化管理
- 响应式变化
- 操作简洁(vuex 提供了一些辅助函数)

state:存数据
getters:计算属性
mutations:修改 state 的唯一途径
actions:异步方法
state
state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 中的 state 中存储,示例代码如下:
const store = new Vuex.Store({
state: {
title: '仓库大标题',
count: 100
}
})
获取 state 数据方式:
-
通过
$store
直接访问-
模板中:
{{ $store.state.xxx }}
-
组件 JS 中:
this.$store.state.xxx
-
JS 模块中:
store.state.xxx
-
-
通过辅助函数
mapState
映射计算属性(简写方式)-
导入
mapState
import { mapState } from 'vuex'
-
使用展开运算符将导出的状态映射给计算属性
computed: { ...mapState(['count']) // mapState(['count']) 是一个对象 // ...mapState(['count']) 就等于下面: // count () { // return this.$store.state.count // } }
-
模板使用:
<div> state的数据:{{ count }}</div>
-
mutations
vuex 同样遵循单向数据流,组件中不能直接修改仓库的数据
-
mutations 是一个对象,对象中存放修改 state 的方法,示例代码如下:
const store = new Vuex.Store({ strict: true, state: { title: '仓库大标题', count: 100 }, mutations: { // 第一个参数是 state,第二个参数是传来的参数 addCount (state) { state.count += 1 }, addFive (state, n) { state.count += n }, changeTitle (state, obj) { state.title = obj.newTitle } } })
-
组件中提交 mutations,可以传参,示例代码如下:
methods: { handleAdd () { this.$store.commit('addCount') }, handleFive () { this.$store.commit('addFive', 5) }, changeFn () { this.$store.commit('changeTitle', { newTitle: '新标题' }) } }
mapMutations
辅助函数 mapMutations
用来简化代码,用法和 mapState
类似,示例代码如下:
mutations: {
subCount (state, n) {
state.count -= n
},
}
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['subCount'])
// 等价于下面:
// subCount (n) {
// this.$store.commit('subCount', n)
// },
}
actions
- 因为 mutations 是同步的,所以用 actions 处理异步操作
- actions 不能直接操作 state,还是需要通过提交来改变数据
示例代码如下:
-
定义 actions
const store = new Vuex.Store({ strict: true, state: { title: '仓库大标题', count: 100 }, mutations: { addFive (state, n) { state.count += n } }, actions: { // context 理解为 store changeCountAction (context, num) { // 异步操作 setTimeout(() => { context.commit('addFive', num) }, 1000) } } })
-
组件中通过
dispatch
调用handleChange () { // 调用 action this.$store.dispatch('changeCountAction', 666) }
mapActions
辅助函数 mapActions 把位于 actions 中的方法提取了出来,映射到 methods 中,简化代码
示例代码如下:
import { mapActions } from 'vuex'
methods: {
...mapActions(['changeCountAction'])
}
// ...mapActions(['changeCountAction']) 映射的代码 本质上是以下代码的写法
// changeCountAction (n) {
// this.$store.dispatch('changeCountAction', n)
// },
模板调用:
<button @click="changeCountAction(200)">+异步</button>
getters
- 除了 state 之外,有时我们还需要从 state 中筛选出符合条件的一些数据,这些数据是依赖 state 的,此时会用到 getters
- 类似于计算属性 computed,但是 getters 不能修改数据
例如:state 中定义了 list 为 1 - 10 的数组,组件中需要显示所有大于 5 的数据:
const store = new Vuex.Store({
strict: true,
state: {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
getters: {
// 第一个参数是 state
filterList (state) {
return state.list.filter(iter => iter > 5)
}
}
})
模板中使用:
<div>{{ $store.getters.filterList }}</div>
mapGetters
辅助函数 mapGetters,写在 computed 中:
computed: {
...mapGetters(['filterList'])
}
模块 module
当项目变得越来越大的时候,为了能让 Vuex 方便维护,就有了 Vuex 的模块化
基本语法
-
定义模块( js 文件)
// user 模块 const state = { userInfo: { name: 'zs', age: 18 }, score: 80 } const mutations = {} const actions = {} const getters = {} export default { state, mutations, actions, getters }
-
在 store 中配置 modules
import user from './modules/User' const store = new Vuex.Store({ modules: { user, } })
访问 state
尽管已经分模块了,但其实子模块的状态,还是会挂到根级别的 state 中,属性名就是模块名
访问:
- 直接通过模块名访问
$store.state.模块名.xxx
- 通过
mapState
映射:- 默认根级别的映射:
mapState([ 'xxx' ])
- 子模块的映射:
mapState('模块名', ['xxx'])
,需要开启命名空间(namespaced)
- 默认根级别的映射:
模块开启命名空间:
export default { namespaced: true, state, mutations, actions, getters }
访问 getters
- 直接通过模块名访问:
$store.getters['模块名/xxx ']
- 通过 mapGetters 映射:
- 默认根级别的映射:
mapGetters([ 'xxx' ])
- 子模块的映射:
mapGetters('模块名', ['xxx'])
,需要开启命名空间
- 默认根级别的映射:
访问 mutations
- 直接通过 store 调用:
$store.commit('模块名/xxx ', 额外参数)
- 通过 mapMutations 映射:
- 默认根级别的映射:
mapMutations([ 'xxx' ])
- 子模块的映射:
mapMutations('模块名', ['xxx'])
,需要开启命名空间
- 默认根级别的映射:
访问 actions
- 直接通过 store 调用:
$store.dispatch('模块名/xxx ', 额外参数)
- 通过 mapActions 映射:
- 默认根级别的映射:
mapActions([ 'xxx' ])
- 子模块的映射:
mapActions('模块名', ['xxx'])
,需要开启命名空间
- 默认根级别的映射: