(一)Vue模板編譯
在Vue中我們有三種方式來創建HTML
- 模板
- 手動寫渲染函數
- JSX
渲染函數是最原始的方法,而模板最終會通過編譯轉換陳渲染函數。渲染函數執行後,會得到一份vnode用來渲染真實DOM。所以,模板編譯其實是配合虛擬DOM進行渲染。
1. 什麼是模板編譯?
所謂模板編譯就是把模板編譯成vnode的渲染函數。
2. 模板編譯過程:
模板編譯可以分爲三個階段:
-
將模板解析爲AST(抽象語法樹)—— 解析器
-
遍歷AST,對 AST 進行靜態節點標記,主要用來做虛擬DOM的渲染優化 —— 優化器
-
使用AST生成render函數代碼字符串—— 代碼生成器
關於模板編譯的源碼可以在vue-template-compiler
包中查看。
(二)Vue虛擬DOM
1. Virtual DOM
概念:
Virtual DOM是一個能夠直接描述一段HTML DOM結構的JavaScript對象,瀏覽器可以根據它的結構按照一定規則創建出確定唯一的HTML DOM結構。
實現原理:
Virtual DOM模式來控制頁面DOM結構更新的過程:創建原始頁面或組件的Virtual DOM結構,用戶操作後需要進行DOM更新時,生成用戶操作後頁面或組件的Virtual DOM結構並與之前的結構進行比對,找到最小變化Virtual DOM的差異化描述對象,最後把差異化的Virtual DOM根據特定的規則渲染到頁面上。
所以核心操作可以抽象成三個步驟:
- 創建Virtual DOM
- 對比兩個Virtual DOM生成差異化Virtual DOM
- 將差異化Virtual DOM渲染到頁面上
優勢:
Virtual DOM的交互模式減少了MVVM或其他框架中對DOM的掃描和操作次數,並且在數據發生改變後只在合適的地方根據JavaScript對象來進行最小化的頁面DOM操作,避免大量重新渲染。
Virtual DOM交互模式的優勢 與以前交互模式相比,Virtual DOM最本質的區別在於減少了對DOM對象的操作,通過JavaScript 對象來代替DOM對象樹,並且在頁面結構改變進行最小代價的DOM渲染操作,提高了交互的性能和效率。這也是提高前端交互性能的根本原因。
2. Vue實現虛擬DOM原理
Vue具體如何實現虛擬DOM(待更新…)
vue2爲什麼要引入虛擬Dom,談談對虛擬Dom的理解?
- 隨着現代應用對頁面的功能要求越複雜,管理的狀態越多,如果還是使用之前的
JavaScript
線程去頻繁操作GUI
線程的碩大Dom
,對性能會有很大的損耗,而且也會造成狀態難以管理,邏輯混亂等情況。引入虛擬Dom
後,在框架的內部就將虛擬Dom
樹形結構與真實Dom
做了映射,讓我們不用在命令式的去操作Dom
,可以將重心轉爲去維護這棵樹形結構內的狀態即可,狀態的變化就會驅動Dom
發生改變,具體的Dom
操作vue
幫我們完成,而且這些大部分可以在JavaScript
線程完成,性能更高。 - 虛擬
Dom
只是一種數據結構,可以讓它不僅僅使用在瀏覽器環境,還可以用與SSR
以及Weex
等場景。
(三)模板轉換成視圖的過程
Vue.js通過編譯將template 模板轉換成渲染函數(render ) ,執行渲染函數就可以得到一個虛擬節點樹
在對 Model 進行操作的時候,會觸發對應 Dep 中的 Watcher 對象。Watcher 對象會調用對應的 update 來修改視圖。這個過程主要是將新舊虛擬節點進行差異對比,然後根據對比結果進行DOM操作來更新視圖。
簡單點講,在Vue的底層實現上,Vue將模板編譯成虛擬DOM渲染函數。結合Vue自帶的響應系統,在狀態改變時,Vue能夠智能地計算出重新渲染組件的最小代價並應到DOM操作上。
我們先對上圖幾個概念加以解釋:
- 渲染函數:渲染函數是用來生成Virtual DOM的。Vue推薦使用模板來構建我們的應用界面,在底層實現中Vue會將模板編譯成渲染函數,當然我們也可以不寫模板,直接寫渲染函數,以獲得更好的控制。
- VNode 虛擬節點:它可以代表一個真實的 dom 節點。通過 createElement 方法能將 VNode 渲染成 dom 節點。簡單地說,vnode可以理解成節點描述對象,它描述了應該怎樣去創建真實的DOM節點。
- patch(也叫做patching算法):虛擬DOM最核心的部分,它可以將vnode渲染成真實的DOM,這個過程是對比新舊虛擬節點之間有哪些不同,然後根據對比結果找出需要更新的的節點進行更新。這點我們從單詞含義就可以看出, patch本身就有補丁、修補的意思,其實際作用是在現有DOM上進行修改來實現更新視圖的目的。Vue的Virtual DOM Patching算法是基於Snabbdom的實現,並在些基礎上作了很多的調整和改進。
附上 Vue2.0 模板渲染過程:
此文是對網上查找的資料的學習筆記,由於還未深入源碼,所以對Vue模板編譯的具體過程還有疑惑。
疑惑:
-
到底在什麼時候進行模板編譯?
我覺得,Vue官方的Vue生命週期圖和上面的模板渲染過程有些出入,加上網上博客說法不一,實在是困惑。
-
靜態模板 、動態模板是什麼?
-
模板渲染 、模板編譯具體區別?