installModule 中发生了什么
// 传入的参数 store:store, rootState:state, path:[], module:root, hot:boolean
var isRoot = !path.length;
// 获取别名 namespaced 为true 的情况下
var namespace = store._modules.getNamespace(path);
// register in namespace map
// 别名表示唯一
if (module.namespaced) {
store._modulesNamespaceMap[namespace] = module;
}
// set state
if (!isRoot && !hot) {
// 强制更新 moduleName 对应的数据
// 这一步修改 对应的 module
var parentState = getNestedState(rootState, path.slice(0, -1));
var moduleName = path[path.length - 1];
store._withCommit(function () {
Vue.set(parentState, moduleName, module.state);
});
}
// 生成了一个对象
// 里面有 commit,dispatch,getters,state,里面所执行的都是 每个module自身
// 还有根据 namespace 是否为空,commit,dispatch 有特别的封装
var local = module.context = makeLocalContext(store, namespace, path);
// 存入_mutations 对象中,并创建 数组,便于同名的mutation操作
// 函数回调 返回 state, 一个外界传入的参数
module.forEachMutation(function (mutation, key) {
var namespacedType = namespace + key;
registerMutation(store, namespacedType, mutation, local);
});
// 存入_actions 对象中,并创建 数组,便于同名的action操作
// 函数回调 返回 store, {
//dispatch: local.dispatch, // 自身 dispatch
//commit: local.commit, // 自身 dispatch
//getters: local.getters, // 自身 getters
//state: local.state, // 自身 state
//rootGetters: store.getters, // 全局 getters
// rootState: store.state // 全局 state
//},外界传入的参数,一个回调函数
module.forEachAction(function (action, key) {
var type = action.root ? key : namespace + key;
var handler = action.handler || action;
registerAction(store, type, handler, local);
});
// 存入 _wrappedGetters 对象,后者居上,重复的会覆盖
// 返回 参数
//local.state, // local state
//local.getters, // local getters
//store.state, // root state
//store.getters // root getters
module.forEachGetter(function (getter, key) {
var namespacedType = namespace + key;
registerGetter(store, namespacedType, getter, local);
});
// 重复执行以上
module.forEachChild(function (child, key) {
installModule(store, rootState, path.concat(key), child, hot);
});
resetStoreVM() 中发生了什么
function resetStoreVM(store, state, hot) {
var oldVm = store._vm;
// bind store public getters
store.getters = {};
var wrappedGetters = store._wrappedGetters;
// getters 封装成了计算属性
var computed = {};
forEachValue(wrappedGetters, function (fn, key) {
// use computed to leverage its lazy-caching mechanism
// direct inline function use will lead to closure preserving oldVm.
// using partial to return function with only arguments preserved in closure enviroment.
computed[key] = partial(fn, store);
Object.defineProperty(store.getters, key, {
get: function () {
return store._vm[key];
},
enumerable: true // for local getters
});
});
// use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
var silent = Vue.config.silent;
Vue.config.silent = true;
// 多了一个_vm
store._vm = new Vue({
data: {
?state: state
},
computed: computed
});
Vue.config.silent = silent;
// enable strict mode for new vm
// 严格模式 深度监听?state,切勿在发布模式下使用,影响性能
if (store.strict) {
enableStrictMode(store);
}
// 卸载Vue
if (oldVm) {
if (hot) {
// dispatch changes in all subscribed watchers
// to force getter re-evaluation for hot reloading.
store._withCommit(function () {
oldVm._data.?state = null;
});
}
Vue.nextTick(function () {
return oldVm.$destroy();
});
}
}
回顾一下,整个new Stroe
开始先是校验传入的options, 到 new ModuleCollection 初始化了 root(new Module) 根节点,之后遍历 options.modules追加入了root._children中。
installModule 这一环节初始化了actions,getters,mutatuion存入store 中。
resetStoreVM 监听了创建了_vm Vue对象,getter 计算属性的绑定。
Vuex(三)