Vuex(一)

449 阅读2分钟

Vuex源码个人学习记录(3.1.1版本)

Vuex的基本目录结构

思维导图

│  │
│  ├─store
│  │  │  --index.js
│  │  │  --state.js
│  │  │  --getters.js
│  │  │  --actions.js
│  │  │  --mutations.js
│  │  │  --modlue
│  │         --aModule.js
│  │         --bModule.js
new Sotre传入的参数
options参数 描述 例子
state 初始状态数据 state二种写法 1:对象形式({a:1}) 2:函数返回对象(function(){return{a:1}})
getters 类似计算属性缓存值,直接获取内容,store直接调用。 getters二种写法 1: 直接返回对象 2:返回函数
mutations 同步事件函数,多个Module有相同命名,会存入数组,遍历触发,store使用commit触发 普通函数
actions 异步事件函数,多个Module有相同命名,会存入数组,再出发函数之前有个before派发事件,执行异步事件(Promise),之后再执行after派发事件 普通函数
modules module模块,从上至下的模块分割 对象
strict 严格模式,布尔值,state值得改变不是由mutation函数引起的都会抛出错误。如果开启会影响性能。 布尔值
plugins 暴露mutation的钩子,利于数据的交互,如socket 的数据出传递 函数,接受{type: type, payload: payload},store.state
namespaced 命名空间,保证唯一性。默认false,如果为true 那么将会加上一个前缀如:stroe.state.a.aModule,store.commit('a/add')
new Store 发生了什么
     var this$1 = this;
        // options校验
        if (options === void 0) options = {};
        // 初始化绑定
        if (!Vue && typeof window !== 'undefined' && window.Vue) {
            install(window.Vue);
        }
        {
            assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
            assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
            assert(this instanceof Store, "store must be called with the new operator.");
        }

        var plugins = options.plugins;
        if (plugins === void 0) plugins = [];
        var strict = options.strict;
        if (strict === void 0) strict = false;

        // store internal state
        this._committing = false;
        this._actions = Object.create(null);
        this._actionSubscribers = [];
        this._mutations = Object.create(null);
        this._wrappedGetters = Object.create(null);
        this._modules = new ModuleCollection(options);
        this._modulesNamespaceMap = Object.create(null);
        this._subscribers = [];
        this._watcherVM = new Vue();

        // bind commit and dispatch to self
        var store = this;
        var ref = this;
        var dispatch = ref.dispatch;
        var commit = ref.commit;
        // actions
        this.dispatch = function boundDispatch(type, payload) {
            return dispatch.call(store, type, payload)
        };
        // mutations
        this.commit = function boundCommit(type, payload, options) {
            return commit.call(store, type, payload, options)
        };

        // strict mode
        this.strict = strict;

        var state = this._modules.root.state;

        // init root module.
        // this also recursively registers all sub-modules
        // and collects all module getters inside this._wrappedGetters
        installModule(this, state, [], this._modules.root);

        // initialize the store vm, which is responsible for the reactivity
        // (also registers _wrappedGetters as computed properties)
        resetStoreVM(this, state);

        // apply plugins
        plugins.forEach(function (plugin) {
            return plugin(this$1);
        });

        var useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools;
        if (useDevtools) {
            devtoolPlugin(this);
        }

1.options的校验。
2.install(Window.Vue)。

    function applyMixin(Vue) {
        // 版本号获取
        var version = Number(Vue.version.split('.')[0]);
        // 根据版本选择方式
        if (version >= 2) {
            //2.0以后有了混入,插入在beforeCreate 生命周期运行 此函数
            Vue.mixin({beforeCreate: vuexInit});
        } else {
            // 标记 初始化init函数
            var _init = Vue.prototype._init;
            Vue.prototype._init = function (options) {
                if (options === void 0) options = {};
                // 从options中获取初始化 init 函数 存入数组,
                options.init = options.init
                    ? [vuexInit].concat(options.init)
                    : vuexInit;
                    // 标记函数重新执行 回调
                _init.call(this, options);
            };
        }
        // store 的获取
        function vuexInit() {
            var options = this.$options;
            // store injection
            if (options.store) {
                this.$store = typeof options.store === 'function'
                    ? options.store()
                    : options.store;
            } else if (options.parent && options.parent.$store) {
                this.$store = options.parent.$store;
            }
        }
    }

3.在 new ModuleCollection 之前初始化了一些基本东西

       // 利于mumation 交互的钩子函数
       var plugins = options.plugins;
       if (plugins === void 0) plugins = [];
       var strict = options.strict;
       // 严格模式
       if (strict === void 0) strict = false;

       // store internal state
       // 标记严格模式下,是否用了_withCommit 来修改state。起到标记作用
       // 默认false, 如果开启了严格模式在mutation 函数外修改state,将会报错。
       this._committing = false;
       // actions 存入对象
       this._actions = Object.create(null);
       // 事件派发数组
       this._actionSubscribers = [];
       // mutations 存入对象
       this._mutations = Object.create(null);
       // getters 存入对象
       this._wrappedGetters = Object.create(null);
  1. new ModuleCollection 做的一些事情
        // register root module (Vuex.Store options)
        this.register([], rawRootModule, false);
        --------------------------------------------------------------------------------
        // path
        // rawModule 
        // runtime 标记生产默认false
        ModuleCollection.prototype.register = function register(path, rawModule, runtime) {
        // rawModule -> options
        var this$1 = this;
        if (runtime === void 0) runtime = true;

        // 验证 getter,actions,mutations
        // 其中 actions 中 可以为 函数,对象,但是对象中必须有 handler 函数
        {
            assertRawModule(path, rawModule);
        }
        // 初始化Module
        // 初始化 state
        // state 可以为函数,也可以是对象
        var newModule = new Module(rawModule, runtime);
        if (path.length === 0) {
            // 创建了一个 root 根节点
            this.root = newModule;
        } else {
            // modules 中的数据才会进来,当做根节点的 子项
            var parent = this.get(path.slice(0, -1));
            parent.addChild(path[path.length - 1], newModule);
        }
        // 创建多个 modules 数组形式
        // 正常情况一个 modules
        // register nested modules
        if (rawModule.modules) {
            // 重复初始化Module
            forEachValue(rawModule.modules, function (rawChildModule, key) {
                // modules 中的对象值
                this$1.register(path.concat(key), rawChildModule, runtime);
            });
        }
    };
  1. new Module 做的一些事情
        this.runtime = runtime;
        // Store some children item
        // 初始化_children
        this._children = Object.create(null);
        // Store the origin module object which passed by programmer
        // options 放入 _rawModule
        this._rawModule = rawModule;
        var rawState = rawModule.state;
        // 初始化 state
        // Store the origin module's state
        this.state = (typeof rawState === 'function' ? rawState() : rawState) || {};
  1. installModule() 函数执行之前
        // 初始化 namespacedMap 对象
        this._modulesNamespaceMap = Object.create(null);
        // mutation 派发事件数组
        this._subscribers = [];
        // Vue 对象
        this._watcherVM = new Vue();

        // bind commit and dispatch to self
        var store = this;
        var ref = this;
        var dispatch = ref.dispatch;
        var commit = ref.commit;
        // 重写 dispatch commit对象
        this.dispatch = function boundDispatch(type, payload) {
            return dispatch.call(store, type, payload)
        };
        this.commit = function boundCommit(type, payload, options) {
            return commit.call(store, type, payload, options)
        };
        // strict mode
        this.strict = strict;
        var state = this._modules.root.state;

Vuex(二)
Vuex(三)