Vuex源碼學習(四)module與moduleCollection

若是你還不知道Vuex是怎麼安裝的,請移步Vuex源碼學習(三)install都作了哪些事情前端

整合模塊

這一節該分析模塊的是怎麼被整合的,以及要整合成什麼樣子。vue


在Vuex的constructor中比較靠前的位置有這麼兩行代碼,_modules屬性是ModuleCollection的實例對象,以後 _modules屬性被頻繁使用,vue-router

這塊就是對Vuex的模塊進行了一次整合,整合出一個能夠被使用的 _modules,而_moduleNamespaceMap是一個空對象segmentfault

該怎麼整合模塊?

先看一下咱們咱們項目中Store的結構
store/index.js

moduleList:數組

moduleSet:框架

結構就是這樣的

在以上代碼中的modules下的數據,我都稱它是僞(未加工)模塊,由於它還不具備模塊的功能。
當咱們實例化Vuex.Store這個類的時候接收的參數options就會直接交給moduleCollection來處理。參數options是什麼呢?就是上面圖中這樣結構的數據,
想要處理成什麼樣子?
下面看一下ModuleCollection是怎麼處理的dom

export default class ModuleCollection {
  constructor (rawRootModule) {
    // register root module (Vuex.Store options)
    // 註冊模塊並連接
    this.register([], rawRootModule, false)
  }
  ...
  register (path, rawModule, runtime = true) {
    if (process.env.NODE_ENV !== 'production') {
     // 不符合規則的模塊會報錯。
      assertRawModule(path, rawModule)
    }
    // 建立一個模塊
    const newModule = new Module(rawModule, runtime)
    if (path.length === 0) {
      this.root = newModule
    } else {
      // path.slice(0,-1)就能夠拿到父模塊的path。
      // get方法能夠根據path來找到對應的模塊。
      const parent = this.get(path.slice(0, -1))
      // 將子模塊掛載到父模塊上
      parent.addChild(path[path.length - 1], newModule)
    }
    // register nested modules
    if (rawModule.modules) {
      // 遍歷每一個模塊的modules(目的是獲取全部子模塊)
      forEachValue(rawModule.modules, (rawChildModule, key) => {
      // 爲何要path.concat(key)?
        // 依次註冊子模塊。
        this.register(path.concat(key), rawChildModule, runtime)
      })
    }
  }
}

在Vuex與vue-router的源碼中,命名變量是頗有規律的,
在開發人員使用這兩個框架的時候,傳遞進去的參數,在使用時命名的變量名都是raw開頭的,表明是未通過加工的。學習

將未通過加工的僞模塊處理成真正可使用的模塊。

在初始化的時候直接開始註冊模塊,
moduleCollection的這個類的任務是把生成的模塊合理的連接起來,而模塊的生成交給了Module這個類。this

因此register方法就是把根模塊以及全部的子模塊從一個僞(未加工)模塊變成一個真正的模塊而且連接起來。
遍歷樹形結構用什麼方法? 遞歸!spa

register都作了什麼?

  1. 篩選出不符合規則的模塊,報錯提示。
  2. 將僞(未加工)模塊加工成一個真正的模塊。
  3. 將加工好的模塊掛載在它的父模塊上。
  4. 若是這個模塊有modules屬性(模塊有本身的子模塊)讓每一個子模塊重複以上操做

遞歸的出口:rawModule.modules爲false(模塊沒有子模塊) ,也就是每一個模塊都沒有子模塊須要註冊了,那就表明所有加工與連接完畢。

分析register的三個參數

register接收三個參數,path、rawModule、hot。

hot這個參數目前看來不關鍵。

rawModule是僞(未加工)模塊

那path的做用是什麼呢?

path的做用很大,你們類比下前端頁面的dom樹的Xpath,若是我想知道這個節點的位置,須要知道這個父節點的位置,而後一層一層的向上知道根結點,有了Xpath就能夠直接找到這個節點,

Vuex也是同樣的想知道某個模塊的位置,只須要提供根結點到他的一個path,path按順序存儲着根模塊到它自己的全部祖先模塊(根模塊沒有名字,又不能把第一個放一個空,因此path裏 面沒有根模塊),在每次註冊的時候,這個模塊有子模塊,就把它的path加上(concat)子模塊的名字,在子模塊執行register方法時,path就比它的父模塊多一個父模塊的名字,因此根模塊註冊的時候傳入path就是[](空數組)了。

ModuleCollection的get方法能夠根據path來獲取指定的模塊,在掛載的時候十分有用,

,使用reduce的方法,按照數組的順序,一層一層的找目標模塊。

path對之後要講的設置命名空間也頗有幫助。

總結

  1. ModuleCollection這個類,主要完成了模塊的連接與整合,生成模塊的任務交給了Module這個類。
  2. 模塊的連接與整合經過遞歸完成。
  3. path可讓moduleCollection快速找到對應模塊。

下一章講述生成的module具體能夠作什麼

我是一個應屆生,最近和朋友們維護了一個公衆號,內容是咱們在從應屆生過渡到開發這一路所踩過的坑,已經咱們一步步學習的記錄,若是感興趣的朋友能夠關注一下,一同加油~

我的公衆號:鹹魚正翻身

相關文章
相關標籤/搜索