模块化思想
import global from './modules/global';
import form from './modules/form';
import formDesign from './modules/form-design';
...
const store = new Vuex.Store({
state: {},
mutations: {},
actions: {},
strict: true,
modules: {
global,
form,
formDesign,
...
},
...
}
此时这个项目结构就很简单清晰啦 ,我们来看看模块的状态管理器长啥样
其实就是和状态管理器一样,有state有mutations ,甚至你喜欢的话,还可以往里面继续嵌套模块module。形成三级、四级、五级等等多层级的模块化状态管理器。
命名空间
上面看到,我们把主状态管理器分割为多个模块。默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的,这样使得多个模块能够对同一 mutation 或 action作出响应。所以我们需要单独的命名空间保证模块化管理的封装度和复用性。
首先我们需要在单个模块中通过添加namespaced:true的方式使其成为带命名空间的模块,也就是刚才我们看到的:
const file = {
namespaced: true,
state: {
fileName:'小文件',
...
},
mutations: {
...
},
actions: {
...
},
};
export default file;
此时在组件内部,获取state的方法
this.$store.state.file.fileName
此时在组件内部,获取getters的方法
this.$store.getters['file/fileGetter']
此时在组件内部,执行Mutations的方法
this.$store.commit('file/fileMutation');
此时在组件内部,执行Actions的方法
this.$store.dispatch('file/fileAction')
带命名空间的moduleA,moduleB模块中,获取根store的state ,getters
state数据: 通过rootState参数 即:rootState.属性名
getter方法:通过rootGetters参数来获取 即:rootGetters.countStudentNumber
{
...
actions: {
async init({state,rootState,rootGetters}) {
return rootGetters.countStudentNumber
},
}
}
如果要传承,可以这样写:
// 主store下的
getters: {
applicationAdminPermission: (state) => (appId) =>
state.applicationAdminList.includes(appId),
}
主store的getters里的函数接收state内参和appid外参。子模块moduleA调用这个getters方法并传参:
{
...
actions: {
async checkIt({state,rootState,rootGetters}) {
const checkResult = rootGetters.applicationAdminPermission('usyddjj16236')
},
}
}
如果你想传多个参数,只能以对象的形式传参
// 主store下的
getters: {
applicationAdminPermission: (state) => (appObj) =>
state.applicationAdminList.includes(appObj.appId),
}
{
...
actions: {
async checkIt({state,rootState,rootGetters}) {
const checkResult = rootGetters.applicationAdminPermission({appName:'大傻逼',appId:'usyddjj16236'})
},
}
}
带命名空间的moduleA,moduleB模块中,获取根store的actions和mutations
提交mutations:
actions: {
changeTenant() {
//increment为根store中的mutation
commit('increment',null,{root:true});
}
}
分发actions:
actions: {
changeTenant() {
//increment为根store中的actions
dispatch('increment',{tenant:'xxx'},{root:true});
}
}
其实就是加上{root:true}这个option。而主Vuex下的actions和mutations并不需要特殊处理。
带命名空间的moduleA,moduleB模块中,获取兄弟模块的state和getters
moduleA:
const moduleA = {
namespaced: true,
state: {
title:'我叫moduleA'
},
getters: {
customTitle(state){
return '你好' + state.title
}
}
};
export default moduleA;
moduleB获取moduleA的state和getters
const moduleB = {
namespaced: true,
state: {
title:'我叫moduleB'
},
actions: {
getModuleAstate({
state,
commit,
dispatch,
rootState,
}){
console.log(rootState.moduleA.title)
},
getModuleAGetters({rootGetters}) {
console.log(rootGetters['moduleA/customTitle'])
}
}
};
export default moduleB;
带命名空间的moduleA,moduleB模块中,获取兄弟模块的actions和mutations
moduleA:
const moduleA= {
namespaced: true,
state: {},
mutations: {
Aaaa(state,{val}){
console.log(val)
},
},
actions: {
Abbb({state},{val}){
console.log(val)
},
}
};
export default moduleA;
moduleB:
const ceshi2 = {
namespaced: true,
state: {
},
mutations: {
},
actions: {
hanleChange({
rootState,
}){
commit('moduleA/Aaaa',{val:'你好我的朋友'},{root:true})
dispatch('moduleA/Abbb',{val:'你好我的宝贝'},{root:true})
},
}
};
在带命名空间的模块中,如何将action注册为全局actions
需要完成:
①添加 root: true
②并将这个 action 的定义放在函数 handler 中
//storeAction在命名空间moduleA中,但是它是一个全局actions
const moduleA = {
namespaced:true,
storeAction:{
root:true, //条件1
handler(namespacedContext, payload){//条件2:handler
//namespacedContext 上下文信息
//payload 载荷,即参数
console.log(namespacedContext)
console.log(payload)
alert("我是模块A中的全局storeAction")
}
}
}