1.Vue.js 運行機制全局概覽

Vue.js 運行機制全局概覽

全局概覽

這一節(jié)筆者將為大家介紹一下 Vue.js 內(nèi)部的整個流程陪拘,希望能讓大家對全局有一個整體的印象钟些,然后我們再來逐個模塊進行講解搭儒。從來沒有了解過 Vue.js 實現(xiàn)的同學(xué)可能會對一些內(nèi)容感到疑惑扇丛,這是很正常的,這一節(jié)的目的主要是為了讓大家對整個流程有一個大概的認識擒滑,算是一個概覽預(yù)備的過程,當(dāng)把整本小冊認真讀完以后叉弦,再來閱讀這一節(jié)丐一,相信會有收獲的。

首先我們來看一下筆者畫的內(nèi)部流程圖淹冰。

大家第一次看到這個圖一定是一頭霧水的钝诚,沒有關(guān)系,我們來逐個講一下這些模塊的作用以及調(diào)用關(guān)系榄棵。相信講完之后大家對Vue.js內(nèi)部運行機制會有一個大概的認識凝颇。

初始化及掛載

new Vue() 之后潘拱。 Vue 會調(diào)用 _init 函數(shù)進行初始化,也就是這里的 init 過程拧略,它會初始化生命周期芦岂、事件、 props垫蛆、 methods禽最、 data、 computed 與 watch 等袱饭。其中最重要的是通過 Object.defineProperty 設(shè)置 settergetter 函數(shù)川无,用來實現(xiàn)「響應(yīng)式」以及「依賴收集」,后面會詳細講到虑乖,這里只要有一個印象即可懦趋。

初始化之后調(diào)用 $mount 會掛載組件,如果是運行時編譯疹味,即不存在 render function 但是存在 template 的情況仅叫,需要進行「編譯」步驟。

編譯

compile編譯可以分成 parse糙捺、optimizegenerate 三個階段诫咱,最終需要得到 render function。

parse

parse 會用正則等方式解析 template 模板中的指令洪灯、class坎缭、style等數(shù)據(jù),形成AST签钩。

optimize

optimize 的主要作用是標記 static 靜態(tài)節(jié)點掏呼,這是 Vue 在編譯過程中的一處優(yōu)化,后面當(dāng) update 更新界面時边臼,會有一個 patch 的過程哄尔, diff 算法會直接跳過靜態(tài)節(jié)點,從而減少了比較的過程柠并,優(yōu)化了 patch 的性能岭接。

generate

generate 是將 AST 轉(zhuǎn)化成 render function 字符串的過程,得到結(jié)果是 render 的字符串以及 staticRenderFns 字符串臼予。

在經(jīng)歷過 parse鸣戴、optimizegenerate 這三個階段以后,組件中就會存在渲染 VNode 所需的 render function 了粘拾。

響應(yīng)式

接下來也就是 Vue.js 響應(yīng)式核心部分窄锅。

這里的 gettersetter 已經(jīng)在之前介紹過了,在 init 的時候通過 Object.defineProperty 進行了綁定缰雇,它使得當(dāng)被設(shè)置的對象被讀取的時候會執(zhí)行 getter 函數(shù)入偷,而在當(dāng)被賦值的時候會執(zhí)行 setter 函數(shù)追驴。

當(dāng) render function 被渲染的時候,因為會讀取所需對象的值疏之,所以會觸發(fā) getter 函數(shù)進行「依賴收集」殿雪,「依賴收集」的目的是將觀察者 Watcher 對象存放到當(dāng)前閉包中的訂閱者 Dep 的 subs 中。形成如下所示的這樣一個關(guān)系锋爪。

在修改對象的值的時候丙曙,會觸發(fā)對應(yīng)的 settersetter 通知之前「依賴收集」得到的 Dep 中的每一個 Watcher其骄,告訴它們自己的值改變了亏镰,需要重新渲染視圖。這時候這些 Watcher 就會開始調(diào)用 update 來更新視圖拯爽,當(dāng)然這中間還有一個 patch 的過程以及使用隊列來異步更新的策略索抓,這個我們后面再講。

Virtual DOM

我們知道某抓,render function 會被轉(zhuǎn)化成 VNode 節(jié)點纸兔。Virtual DOM 其實就是一棵以 JavaScript 對象( VNode 節(jié)點)作為基礎(chǔ)的樹惰瓜,用對象屬性來描述節(jié)點否副,實際上它只是一層對真實 DOM 的抽象。最終可以通過一系列操作使這棵樹映射到真實環(huán)境上崎坊。由于 Virtual DOM 是以 JavaScript 對象為基礎(chǔ)而不依賴真實平臺環(huán)境备禀,所以使它具有了跨平臺的能力,比如說瀏覽器平臺奈揍、Weex曲尸、Node 等。

比如說下面這樣一個例子:

{
    tag: 'div',                 /*說明這是一個div標簽*/
    children: [                 /*存放該標簽的子節(jié)點*/
        {
            tag: 'a',           /*說明這是一個a標簽*/
            text: 'click me'    /*標簽的內(nèi)容*/
        }
    ]
}

渲染后可以得到

<div>
    <a>click me</a>
</div>

這只是一個簡單的例子男翰,實際上的節(jié)點有更多的屬性來標志節(jié)點另患,比如 isStatic (代表是否為靜態(tài)節(jié)點)、 isComment (代表是否為注釋節(jié)點)等蛾绎。

更新視圖

前面我們說到昆箕,在修改一個對象值的時候,會通過 setter -> Watcher -> update 的流程來修改對應(yīng)的視圖租冠,那么最終是如何更新視圖的呢鹏倘?

當(dāng)數(shù)據(jù)變化后,執(zhí)行 render function 就可以得到一個新的 VNode 節(jié)點顽爹,我們?nèi)绻胍玫叫碌囊晥D纤泵,最簡單粗暴的方法就是直接解析這個新的 VNode 節(jié)點,然后用 innerHTML 直接全部渲染到真實 DOM 中镜粤。但是其實我們只對其中的一小塊內(nèi)容進行了修改捏题,這樣做似乎有些「浪費」玻褪。

那么我們?yōu)槭裁床荒苤恍薷哪切父淖兞说牡胤健鼓兀窟@個時候就要介紹我們的「patch」了公荧。我們會將新的 VNode 與舊的 VNode 一起傳入 patch 進行比較归园,經(jīng)過 diff 算法得出它們的「差異」。最后我們只需要將這些「差異」的對應(yīng) DOM 進行修改即可稚矿。

再看全局

回過頭再來看看這張圖庸诱,是不是大腦中已經(jīng)有一個大概的脈絡(luò)了呢?

那么晤揣,讓我們繼續(xù)學(xué)習(xí)每一個模塊吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桥爽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子昧识,更是在濱河造成了極大的恐慌钠四,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跪楞,死亡現(xiàn)場離奇詭異缀去,居然都是意外死亡,警方通過查閱死者的電腦和手機甸祭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門缕碎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人池户,你說我怎么就攤上這事咏雌。” “怎么了校焦?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵赊抖,是天一觀的道長。 經(jīng)常有香客問我寨典,道長氛雪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任耸成,我火速辦了婚禮报亩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘墓猎。我一直安慰自己捆昏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布毙沾。 她就那樣靜靜地躺著骗卜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寇仓,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天举户,我揣著相機與錄音,去河邊找鬼遍烦。 笑死俭嘁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的服猪。 我是一名探鬼主播供填,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼罢猪!你這毒婦竟也來了近她?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤膳帕,失蹤者是張志新(化名)和其女友劉穎粘捎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體危彩,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡攒磨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了汤徽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娩缰。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泻骤,靈堂內(nèi)的尸體忽然破棺而出漆羔,到底是詐尸還是另有隱情梧奢,我是刑警寧澤狱掂,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站亲轨,受9級特大地震影響趋惨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惦蚊,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一器虾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蹦锋,春花似錦兆沙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春库正,著一層夾襖步出監(jiān)牢的瞬間曲楚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工褥符, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留龙誊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓喷楣,卻偏偏與公主長得像趟大,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子铣焊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容