Vue源碼編譯過程


Vue源碼編譯過程

一、掛載
初始化$mounted會掛載組件,不存在 render 函數時需要編譯(compile);

二、compile
1.compile 分為 parse,optimize 和 generate,最終得到 render 函數;

2.parse 調用 parseHtml 方法,方法核心是利用正則解析 template 的指令,class 和 stype,得到 AST;

3.optimize 作用標記 static 靜態節點,后面 patch,diff會跳過靜態節點;

4.generate 是將 AST 轉化為 render 函數表達式,執行 vm._render 方法將 render 表達式轉化為VNode,得到 render 和 staticRenderFns 字符串;

5.vm._render 方法調用了 VNode 創建的方法createElement
// render函數表達式
(function() {
with(this){
return _c('div',{ //創建一個 div 元素
attrs:{"id":"app"} //div 添加屬性 id
},[
_m(0), //靜態節點 header,此處對應 staticRenderFns 數組索引為 0 的 render function
_v(" "), //空的文本節點
(message) //判斷 message 是否存在
//如果存在,創建 p 元素,元素里面有文本,值為 toString(message)
?_c('p',[_v("\n "+_s(message)+"\n ")])
//如果不存在,創建 p 元素,元素里面有文本,值為 No message.
:_c('p',[_v("\n No message.\n ")])
]
)
}
})

三、依賴收集與監聽
這部分是數據響應式系統
1.調用 observer(),作用是遍歷對象屬性進行雙向綁定;

2.在 observer 過程中會注冊Object.defineProperty的 get 方法進行依賴收集,依賴收集是將Watcher 對象的實例放入 Dep 中;

3.Object.defineProperty的 set 會調用Dep 對象的 notify 方法通知它內部所有的 Watcher 對象調用對應的 update()進行視圖更新;

4.本質是發布者訂閱模式的應用

四、diff 和 patch
diff 算法對比差異和調用 update更新視圖:

1.patch 的 differ 是將同層的樹節點進行比較,通過唯一的 key 進行區分,時間復雜度只有 O(n);

2.上面將到 set 被觸發會調用 watcher 的 update()修改視圖;

3.update方法里面調用patch()得到同級的VNode 變化;

4.update 方法里面調用createElm通過虛擬節點創建真實的 DOM 並插入到它的父節點中;

5.createElm實質是遍歷虛擬 dom,逆向解析成真實 dom;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM