鲜荣彬
Herry

Vue加载后,将Vuex 加载到 Vue对象上后,初始化Store。

(一) Store的参数的定义

其中 action 与 mutation 的订阅者 用 数组存储,而其属性都是用对象存储的。

考虑了分模块存储思想,这样的存储方式个人觉得确实合理。

constructor (options = {}) {
   const {
            plugins = [],
            strict = false
            } = options
        this._committing = false //提交状态,确保 state只能在mutation的回调函数中修改
        this._actions = Object.create(null) //存储用户定义的所有actions
        this._actionSubscribers = []    //存储所有action的所有订阅者
        this._mutations = Object.create(null) //存储用户定义的所有 mutation
        this._wrappedGetters = Object.create(null) //存储用户定义的所有 getters
        this._modules = new ModuleCollection(options) 
        this._modulesNamespaceMap = Object.create(null) // 存储命名空间,即 namespaced: true 的 module 名字都会被存储起来
        this._subscribers = [] //存储所有对 mutation变化的订阅者
        this._watcherVM = new Vue() //Vue对象的实例,主要利用 $watch来观测变化
}

   然后绑定 commit 与 dispatch 两个方法,指定是否严格模式;

   在严格模式下会观测所有的 state 的变化,官方建议生产环境时,传入参数 strict : false。

     const store = this   
        const { dispatch, commit } = this   //此时的this = Stroe 实例,但是为什么这样设计
        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)
        }
      // enable strict mode for new vm
      if (store.strict) {
        enableStrictMode(store);
      }

难点,核心:

   installModule(this, state, [], this._modules.root); ---- 模块注册与安装

   resetStoreVM(this, state);  ----初始化store._vm,观测state和getters的变化

  整个module的创建整理有以下几个步骤:

  (一)获取 _modulesNamespaceMap 数据。

  (二)不为根模块且非热更新时,设置级联状态(太复杂,没搞懂)。

  (二)循环获取  _mutations 对象数据,其中包含了以模块划分的回调函数数组。

  (三)循环获取 _actions 对象数据,其中包含了以模块划分的回调函数数组

  (四)循环获取 _wrappedGetters对象数据,其中包含了以模块划分的回调函数数组。

    完成后,Store 如下: 

(二) mutation 的注册

  先提出个问题:

    mutation中的自定义的回调函数怎么被调用?

    让我们先回一下,我们是怎么定义自己的 store模块吧。

  

  我们定义的模块都是一个对象,每个对象的属性都有一个key值,但是value却是比较复杂的。  

  为了确保Key不重复,Vuex 开启了命名空间这个功能,即使不同的模块有相同的key值,也不会造成获取Value值被覆盖。

  而Vuex使用 Object.keys()将 可以值转换成数组,从而循环获取希望得到的数据。

module.forEachMutation(function (mutation, key) {
      var namespacedType = namespace + key;
      registerMutation(store, namespacedType, mutation, local);
});

从registerMutaion()函数中,可以看到,因为 store._mutations  是复杂类型,隐藏,entry.push 回调函数后,

store._mutations 立刻拥有了 模块中的 “mutation”所有属性。

而 mutations的收集,其实就是为 $store.commit 服务。

(三) this.$store.commit 定义

   当我们需要更改Store数据时,我们必须通过Mutation去修改数据状态。

      Vuex暴露接口是 $store.commit。

const { dispatch, commit } = this
this.commit = function boundCommit (type, payload, options) {
   return commit.call(store, type, payload, options)
};

  Store原型上的 commit定义如下:

   

 

 

  

 

 

    

   

posted on 2017-12-23 16:40  Herry彬  阅读(377)  评论(0)    收藏  举报