Vue.js源碼分析(二)--mount整體流程

$mount

這一節看掛載,從有編譯的運行時觸發的$mount方法出發,這個函數裏面只有一句話:

el = el && query(el)

這是用來保證el的類型的,我們來看query方法,實現的很直接,如果el是個字符串,使用querySelector拿到DOM節點,沒有這個節點的話,生產環境會報錯;否則返回createElement創建的DOM節點。
如果不是字符串,直接返回el即可。

接着,返回的el不可以是body或者document,這樣直接覆蓋是會破壞HTML結構,因此,這裏做了個判斷+警告。

然後拿到options對象之後,會查看是否有render方法,沒有的話接着看是否有template模板,有的話會做處理,沒有的話會用outerHTML拿到:
在這裏插入圖片描述
最終,template其實是整個我們要掛載的DOM字符串。

如果有render的話就直接render,否則就render剛剛生成的template字符串。這一塊再編譯的時候再具體展開。
在這裏插入圖片描述
接着便走到了之前緩存的mount的方法那裏(之前我們重寫了這個方法),這裏轉到了runtime/index.js裏面。

又一個$mount

這裏調用的是mountComponent方法,定義在instance/lifecycle裏面,其中對傳來的el做了緩存之後,繼續去判斷上一步是不是完成了render,沒有的話就去調用createEmptyVnode創建一個空的VNode。

這裏常見的一個警告就是如果我們使用了沒有compile的runtime版本,在這裏顯然有可能會創建空的VNode,這時就會有各種警告:

'You are using the runtime-only build of Vue where the template ' 
'compiler is not available. Either pre-compile the templates into ' 
'render functions, or use the compiler-included build.',

歸根結底還是沒能生成正確的render函數。

接着會有一些方便埋點的操作和一些生命週期的內容,這裏也先不展開。

最終這裏定義了一個函數:

    updateComponent = () => {
      vm._update(vm._render(), hydrating)
    }

這裏的hydrating我們可以忽略,是服務端渲染的內容,暫時認爲是false即可。前者是通過vm._render渲染的VNode。

接着下面通過new了一個Watcher,裏面使用到了updateComponent函數,這裏的watcher可以看作是個渲染watcher,這裏就要轉到watcher類裏去看看這個和響應式強相關的重要函數。

所謂的render watcher其實就給vm綁定一個_watcher屬性。

    if (isRenderWatcher) {
      vm._watcher = this
    }
    vm._watchers.push(this)

接着很多內容我們先忽略,只需指定再get裏面去call(vm, vm)時即執行剛剛定義的updateComponent函數,自然就執行了vm._update和vm._render兩個函數,當然後者先執行,前者再執行,這裏涉及VNode的內容,下次繼續。

最後提一句爲什麼總要watcher裏面去執行updateComponent,相比大家看到這裏也有感覺了,不僅僅是渲染,我們還需要watch更新,無論如何updateComponent都是必不可少的入口文件,自然需要和watcher強相關。

總結

以後每天讀一部分吧,另外題也要做起來了,越來越覺得數據結構重要了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章