Vue底層學習1——原理解析
全手打原創,轉載請標明出處:https://www.cnblogs.com/dreamsqin/p/14945934.html, 多謝,=。=~(如果對你有幫助的話請幫我點個贊啦)
作為一個Web前端開發人員,使用Vue框架進行專案開發已經有一陣子,掐指一算,是時候認真探索一下Vue的底層了,以前的瞭解比較偏理論,這一次打算在弄清基本原理的前提下自己手寫Vue中的核心部分,也許這樣我才敢說自己“深入理解”了Vue,話不多說,開幹,先聊聊大家熟知的理論部分~
Vue工作機制
初始化
-
在執行
new Vue()
之後,會建立一個Vue例項並進行初始化操作,包括生命週期(beforeCreate
、created
beforeMount
、mounted
、beforeUpdate
、updated
、beforeDestroy
、destroyed
)、事件、props、methods、data、computed、watch等。 -
其中最重要的就是通過
Object.defineProperty
重寫data
物件中各個屬性的setter
及getter
方法,用於實現【響應式】和【依賴收集】。 -
初始化完成後會呼叫
$mount
將Vue例項掛載到指定的dom
節點。
工作流程
基於Vue原始碼整理出了一張總覽圖,我們可以清晰的看到Vue的整個工作機制:
init
即初始化,上面已經對初始化做了簡單概述。compile
template
模板(Vue中的html程式碼)進行掃描,最終生成一些渲染函式,同時實現依賴收集(作用是當資料更新時我們可以知道去介面中更新哪個DOM節點)。render function
即渲染函式,用於生成虛擬DOM樹。我們在做資料更新時,修改的資料並不是進行真實的DOM操作,而是虛擬DOM上的數值,在做更新之前還會進行diff演算法
比較,根據最新值和舊值計算出需要做的最小更新。Watcher
即觀察者,資料發生變化時實現感知,呼叫更新函式,從而進行補丁操作。patch
即補丁操作,根據資料變化實現介面更新。目的是通過JS的計算時間換取DOM操作時間,從而提高效能。核心思想是減少頁面渲染的次數及數量。
Vue響應式原理
為了方便後續手擼MVVM,在上述工作流程的基礎上實現了簡化:
編譯
parse
:使用正則解析template
中的Vue指令(v-xxx)變數等等,最終形成語法樹AST
。optimize
:標記一些靜態節點,用作後面的效能優化,在做diff演算法
的時候直接略過。generate
:把第一部分生成的AST
(抽象語法樹:Abstract Syntax Tree)轉化為渲染函式render function
。
響應式
初始化時通過Object.defineProperty
進行繫結,設定通知機制。當編譯器生成的渲染函式被實際渲染時,會觸發getter
進行依賴收集,在資料變化時觸發setter
進行更新。
虛擬DOM
Virtual DOM
是React首創,Vue2開始支援,就是用JavaScript物件來描述DOM結構,資料修改時,我們先修改虛擬DOM中的資料,然後對資料進行diff演算法
計算,最後彙總所有的diff
,力求做最少的DOM操作,畢竟在js裡面對比很快,而真實的DOM操作太慢。
// VDOM
{
"tag": "div",
"props": {
"name": "dreamsyang",
"style": {
"color": "red"
},
"onClick": xxx
},
"children": [
{
"tag": "a",
"text": "click me"
}
]
}
<div name="dreamsyang" style="color: red;" @click="xxx">
<a>
click me
</a>
</div>
參考資料
1、Vue官方文件:https://cn.vuejs.org/;
2、Vue原始碼:https://github.com/vuejs/vue;