这两天整理项目时发现自己对Vuex模块化的使用还不够熟悉,虽然namespaced: true已经刻在DNA里了,但是读取仓库数据时mapState、 mapActions等辅助函数写得不算很顺畅,所以来复习一下,把整个模块化的流程都自己梳理总结一遍,下一次就可以更加优雅流利地敲代码了。Above all, 开启命名空间并且使用辅助函数会更加方便噢。
首先指路官方文档,更加详细深入的教程。
下面是我的总结:
为什么要模块化
-
Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT (opens new window))”而存在。这也意味着,每个应用将仅仅包含一个 store 实例
-
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿
-
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)
模块 module
每个模块都可配置自己的 state、mutations、actions、getters、甚至是嵌套子模块modules。 但是注意,最终所有独立的模块都是在一个store对象里面。
export default {
namespaced: true,
actions:{
// 奇数再加
oddAdd(context, value) {
// 判断是否为奇数
if (!context.state.sum % 2) {
context.commit('ODDADD', value)
}
},
// 等一会儿先
waitAdd(context, value) {
setTimeout(() => {
context.commit('WAITADD', value)
}, 500)
}
},
mutations:{
ADD(state, value) {
// console.log('mutations被调用了',state,value);
state.sum += value
},
SUBTRACT(state, value) {
state.sum -= value
},
ODDADD(state, value) {
state.sum += value
},
WAITADD(state, value) {
state.sum += value
},
},
state:{
sum: 0,
school: '北京大学',
study: '经济学',
student: 'Lindsay',
},
getters:{
bigSum(state) {
return state.sum * 10 //return决定值
}
}
}
注:以下所有示例代码都基于上面贴出的countOPTIONS模块
模块化使用
- 在store文件夹下新建modules文件夹,里面存放所有独立的模块
- 在index.js中引入各个模块,添加
modules配置项并向外暴露
// 引入Vue 构造函数
import Vue from 'vue'
// 引入Vuex插件
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
import countOPTIONS from './countOPTIONS'
import personOPTIONS from './personOPTIONS'
// 生成store实例的方法--- new Vuex({配置项})
// 创建store实例,同时默认暴露
export default new Vuex.Store({
modules: {
countOPTIONS, personOPTIONS
}
})
namespaced命名空间
开启方式: 在独立的模块中添加配置项 namespaced: true
- 带命名空间的模块,具有更高的封装度和复用性
- 当模块被注册后,它的所有
getter、action及mutation都会自动根据模块注册的路径调整命名。
直接-获取数据
state
语法:$store.state.模块名.state属性名
$store.state.countOPTIONS.sum
getters
语法:$store.getters['模块名/getter属性名']
$store.getters.['countOPTIONS/bigSum']
commit && dispatch
语法:$store.commit('模块名/mutation名') && $store.dispatch('模块名/action名')
$store.commit('countOPTIONS/ADD') $store.dispatch('countOPTIONS/Add')
当获取数据的需求比较大时,通常采用辅助函数
辅助函数-获取数据
// 当然大前提是需要先引入辅助函数
import {mapState,mapActions,mapGetters,mapMutations} from 'vuex'
mapState
写在computed计算属性中,将模块的空间名称字符串作为第一个参数
// 第二个参数
// 1. 写成数组形式(生成的计算属性和state中的数据拥有一样的名称,双引号不能省略)
...mapState('countOPTIONS',["sum", "student", "school", "study"])
// 2. 写成对象形式
...mapState('countOPTIONS',{
sum: state => state.sum,
student: state => state.student,
school: state => state.school,
study: state => state.study,
}
// 自命名生成的计算属性
//...mapState('countOPTIONS',{a:'sum', b:'student', b:'school', d:'study'})
我更喜欢第一种写法,数组的形式写起来简便很多。
下面的3个辅助函数都采取了数组写法,对象写法省略。
mapGetters
// 数组形式 (生成的计算属性和state中的数据拥有一样的名称,双引号不能省略)
...mapGetters('countOPTIONS',["bigSum"])
mapActions && mapMutations
...mapActions('countOPTIONS',["Add", "Subtract"])
...mapMutations('countOPTIONS',["ADD", "SUBTRACT"])