在上一节中,我们已经实现了模块的收集功能,现在就差我们的最后一步,安装模块...
把子模块中所有的getters/mutations/actions全部安装到store中的state/getters/mutations/actions
那么,我们来实现一下,这个安装函数
- 首先,我们需要明确函数的输入,也就是函数需要传入的参数
- 要安装哪个模块 -->rootModule
- 安装到哪里-->store
- 跟模块收集一样,模块安装也是一个递归的过程,因此我们需要一个数组来辅助我们达到目的。
- 我们在把子模块的
state安装到root module时,会用到state,虽然我们可以通过store.state方式进行访问,但为了方便起见,这里还是直接以参数传入。 由此,我们确定了函数需要要传入的参数。
- 对于
mutations和actions来说,可能存在重名的情况,所以我们使用数组进行存储,即把同名属性放到数组中
const installModule = (store,state,path,rootModule)=>{
if(path.length){
let parent = path.slice(0,-1).reduce((state,current)=>{
return state[current]
},state)
// 将state 转变成响应式
Vue.set(parent,path[path.length-1],rootModule.state)
}
let getters = rootModule.raw.getters
if(getters){
forEach(getters,(key,fn)=>{
Obejct.defineProperty(store.getters,key,{
get:()=>{
return fn(rootModule.state)
}
})
})
}
let mutations = rootModule.raw.mutations
if(mutations){
forEach(mutations,(key,fn)=>{
let arr = store.mutations[key]||(store.mutations[key]=[])
arr.push((payload)=>{
fn(store.state,payload)
})
})
}
let actions = rootModule.raw.actions
if(actions){
forEach(actions,(key,fn)=>{
let arr = store.actions[key]||(store.actions[key]=[])
arr.push((payload)=>{
fn(store,payload)
})
})
}
forEach(rootModule.children,(moduleName,module)=>{
installModule(store,state,path.concat(moduleName),module)
})
}
因为store.mutaions[key]可能时一个数组,所以,我们要修改我们的commit函数。
commit(mutationType,paylod){
this.mutations[mutationType].forEach(fn=>fn(payload))
}
同理,对于dispatch方法也应该作相同处理
dispatch(actionType,paylod){
this.actions[actionType].forEach(fn=>fn(payload))
}
完结撒花.... 完整代码: