if (useDevtools) {
devtoolPlugin(this)
}
}
Vuex本身是单一状态树,应用的所有状态都包含在一个大对象内,随着我们应用规模的不断增长,这个Store变得非常臃肿。为了解决这个问题,Vuex允许我们把store分模块。每一个模块包含各自的state、mutations、actions和getters,甚至还可以嵌套模块。
接下来看installModule方法:
function installModule (store, rootState, path, module, hot) {
// 通过path数组的长度判断是否为根
const isRoot = !path.length
const namespace = store._modules.getNamespace(path) // register in namespace map
if (module.namespaced) {
store._modulesNamespaceMap[namespace] = module
}
// 第一次调用时,path为空,不进入if
// 递归调用installModule安装子模块时,将执行该代码块
if (!isRoot && !hot) {
const parentState = getNestedState(rootState, path.slice(0, -1))
// 模块名
const moduleName = path[path.length - 1] // 把当前模块的state添加到parentState中。具体解析见下
store._withCommit(() => {
Vue.set(parentState, moduleName, module.state)
})
}
const local = module.context = makeLocalContext(store, namespace, path)
// 对mutations、actions、getters进行注册
module.forEachMutation((mutation, key) => {
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation, local)
})
module.forEachAction((action, key) => {
const type = action.root ? key : namespace + key
const handler = action.handler || action
registerAction(store, type, handler, local)
})
module.forEachGetter((getter, key) => {
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter, local)
})
// 遍历modules,递归调用installModule安装子模块
module.forEachChild((child, key) => {
installModule(store, rootState, path.concat(key), child, hot)
})
}
store的_withCommit方法定义是这样的:
_withCommit (fn) {
const committing = this._committing
this._committing = true
fn()
this._committing = committing
}
Vuex中所有对state的修改都会用_withCommit函数包装,保证在同步修改state的过程中this._committing的值始终为true。这样当我们观测 state的变化时,如果this._committing的值不为true,则能检查到这个状态修改是有问题的。










