installModule
installModule是在Store类中constructor中执行的方法,主要作用就是对 Vuex 中的 module 进行模块注册,并且通过 plugins.forEach(plugin => plugin(this)) 进行对模块的应用
- 根据路径长度判断是否为根模块,获取命名空间,判断当前模块是否有命名空间,如果有则将其加入 _modulesNamespaceMap 中
- 判断是否为根模块,如果不是则先获取父模块再获取子模块,用 Vue.set 将模块添加到父模块中,使其为响应式的数据
- 获取上下文环境信息
- 依次遍历 getters 、 mutation 、 action 将其分别加入对应的收集队列数组中
- 判断是是否还有 modules 如果则遍历执行 installModule 完成深度遍历 module
/** *
安装模块
* @param {Store} store store 实例
* @param {Store.state} rootState 根 module state
* @param {Array<String>[]} path 模块路径
* @param {Module} module 注册的模块实例
* @param {Boolean} hot
*/
拆分 路径长度--模块
// 判断 路径是不是根模块
const isRoot = !path.length
// 通过 getNamespace 来判断是否为根数组
const namespace = store._modules.getNamespace(path)
// 用户设置了 命名空间 就把 module 赋值给 _modulesNamespaceMap 的命名
// _modulesNamespaceMap
// 收集模块命名空间 用以完成 根据模块区分 state mutation 等功能的 { moduleName : Module }
if (module.namespaced) {
store._modulesNamespaceMap[namespace] = module
}
// 不是根模块
// 先获取父模块再获取子模块,用 Vue.set 将模块添加到父模块中,使其为响应式的数据
if (!isRoot && !hot) {
// parentState 删除最后一位
const parentState = getNestedState(rootState, path.slice(0, -1))
// 对应取 moduleName
const moduleName = path[path.length - 1]
store._withCommit(() => {
Vue.set(parentState, moduleName, module.state)
})
}
getNamespace 函数
作用:
getNamespace这个函数,就是从根节点开始,reduce寻找子节点,如果子节点有namespace,则把它的key拼接出来,最后返回拼接完整的
拆分 获取上下文环境信息
const local = module.context = makeLocalContext(store, namespace, path)
makeLocalContext 函数
function makeLocalContext (store, namespace, path) {
const noNamespace = namespace === ''
const local = {
dispatch: noNamespace ? store.dispatch : (_type, _payload, _options) => {
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
return
}
return store.dispatch(type, payload)
},
commit: noNamespace ? store.commit : (_type, _payload, _options) => {
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
return
}
store.commit(type, payload, options)
}
}
Object.defineProperties(local, {
getters: {
get: noNamespace
? () => store.getters
: () => makeLocalGetters(store, namespace)
},
state: {
get: () => getNestedState(store.state, path)
}
})
return local
}
拆分 依次遍历 getters、mutation、action 将其分别加入对应的收集队列数组中
把对应模块的对应getters、mutation、action放入收集数组中
mutation
module.forEachMutation((mutation, key) => {
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation, local)
})
action
module.forEachAction((action, key) => {
const type = action.root ? key : namespace + key
const handler = action.handler || action
registerAction(store, type, handler, local)
})
getters
module.forEachGetter((getter, key) => {
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter, local)
})
拆分 判断是是否还有 modules 如果则遍历执行 installModule 完成深度遍历 module
重新执行 installModule
module.forEachChild((child, key) => {
installModule(store, rootState, path.concat(key), child, hot)
})