Vue 的模板編譯是在 $mount 的過程中進行的,在 $mount 的時候執行了 compile 方法來將 template 里的內容轉換成真正的 HTML 代碼。
complie 最終生成 render 函數字符串,等待調用。這個方法分為三步:
- parse 函數解析 template
- optimize 函數優化靜態內容
- generate 函數創建 render 函數字符串
parse解析
AST 的全稱是 Abstract Syntax Tree,也就是所謂抽象語法樹。每一個 AST 節點存放的就是我們的 HTML 元素、插值表達式或文本內容。AST 正是 parse 函數生成和返回的。
Optimize() 優化
會對 parse 生成的 AST 進行靜態內容的優化。靜態內容指的是和數據沒有關系,不需要每次都刷新的內容。標記靜態節點的作用是為了在后面做 Vnode 的 diff 時起作用,用來確認一個節點是否應該做 patch 還是直接跳過。optimize 的過程分為兩步:
- 標記所有的靜態和非靜態結點
- 標記靜態根節點
Generate()
Generate 函數的輸入也是 AST,它遞歸了 AST 樹,為不同的 AST 節點創建了不同的內部調用方法,等待后面的調用。生成 render 函數字符串。
經過解析后,接下來 Vue 做的事情就是 new watcher(),這個時候會對綁定的數據執行監聽,render 函數就是數據監聽的回調所調用的,其結果便是重新生成 vnode。
當這個 render 函數字符串在第一次 mount、或綁定的數據更新的時候,都會被調用,生成 Vnode。
如果是數據的更新,那么 Vnode 會與數據改變之前的 Vnode 做 diff,對內容做改動之后,就會更新到我們真正的 DOM 上。