前言
Vux是单一状态树,所有的状态会集中为一个比较大的对象。当应用非常复杂时,store对象就会变得臃肿。
因此,Vuex允许分割模块,每个模块拥有自己的state、getter、mutation、action、module(嵌套子模块)。
一、文件结构
相比普通的Vuex,模块化的Vuex需要一个modules文件夹来存放不同的模块。
官方标准是一个模块一个js文件,当然模块复杂的话,也可以拆分出来。
// store 目录结构
| actions.js
| getters.js
| index.js
| mutations.js
| state.js
| modules
| user.js
| Constant
| index.js
| mutations.js
| state.js
然后在store下的index.js中引入这些文件,并导出:
import user from "./modules/user"
import constant from './modules/Constant/index'
export default new Vuex.Store({
state,
actions,
getters,
mutations,
modules:{
user,
constant
}
})
二、模块的局部状态
- getter
//getter有三个参数,第一个是模块内的state,第二个是模块内的getters,第三个是根节点状态rootState
const getters = {
bFullName: (state, getter, rootState) => {}
}
- mutation
//mutation 接受两个参数 第一个参数是模块内的state,第二个参数与根状态定义的一样,是传递的其他参数
const mutations = {
incremaent(state, payload){}
}
- action
//action 第一个参数还是context对象,这个对象的state是模块内的状态,rootState指根状态
const actions = {
aysnc_set_name({state, commit, rootState}, payload){}
}
getter,mutation,action默认是注册在全局命名空间的,所以可以和使用根状态一样直接使用他们。
state使用时用加上模块名。
this.$store.state.Constant.name;
...mapState({
name: state => state.Constant.bName
})
三、命名空间
由于getter,action,mutation默认是注册在全局命名空间的,所以容易造成命名冲突的问题。为了解决这个问题,Vuex可以设置了、模块命名空间。通过给模块添加namespaced:true使其拥有自己的命名空间,这时getter,mutation,action都会自动根据模块注册的路径调整命名。
const moduleDemo = {
namespaced:true,
state,
mutation
}
export default moduleDemo
这时,要想调用模块的getter,action,mutation就要加上一层目录。
this.$store.getters['Constant/getName']
...mapGetters({
constantName:'Constant/getName'
})
this.$store.commit('Constant/setName',{name:'11'})
...mapMutations({
setName: 'Constant/setName'
})
this.$store.dispatch('Constant/async_set_name', {name:'99'})
...mapActions({
async_set_name:'Constant/async_set_name'
})
这样每次都要写模块名,为了简化操作,辅助函数提供了一个参数来绑定命名空间。
...mapState('Constant', {
name:state => state.name
})
...mapMutations('Constant', {
name: 'setName'
})
...mapActions('Constant', {
async_set_name: 'async_set_name'
})
而且可以使用createNamespaceHelpers创建基于某个命名空间辅助函数。
const {mapState, mapActions} = createNameSpaceHelpers('Constant')
...mapState(['name'])
...mapActions(['foo'])