Vuex(二)

650 阅读2分钟

上一篇Vuex(一)
思维导图与(一)相同

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(三)