vue.js框架原理淺析


vue.js是一個非常優秀的前端開發框架,不是我說的,大家都知道。

首先我現在的能力,獨立閱讀源碼還是有很大壓力的,所幸vue寫的很規范,通過方法名基本可以略知一二,里面的原理不懂的地方多方面查找資料,本文中不規范不正確的地方歡迎指正,學生非常願意接受各位前輩提出寶貴的建議和指導。

使用vue的版本是v2.5.13,采用了flow作為類型管理工具,關於flow相關內容選擇性忽略了,不考慮類型系統,只考慮實現原理,寫下這篇文章。

同步到sau交流社區(首發):https://www.mwcxs.top/page/558.html

本文大概涉及到vue幾個核心的地方:vue實例化,虛擬DOM,模板編譯過程,數據綁定。

 

一、vue的生命周期

 

二、vue實例化

研究vue的實例化就要研究_init方法,此方法定義在src/core/instance/init.js下的initMixin中,里面是對vue實例即vm的處理。其中包括開發環境下的代理配置等一些列處理,並處理了傳遞給構造函數的參數等,重點在一系列方法

    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate') initInjections(vm) // resolve injections before data/props initState(vm) initProvide(vm) // resolve provide after data/props callHook(vm, 'created')

初始化生命周期,初始化事件,初始化渲染,觸發執行beforeCreate生命周期方法,初始化data/props數據監聽,觸發執行created生命周期方法。

對應到生命周期示例圖,created方法執行結束,接下來判斷是否傳入掛載的el節點,如果傳入的話此時就會通過$mount函數把組件掛載到DOM上面,整個vue構造函數就執行完成了。以上是vue對象創建的基本流程。

 

三、模板編譯

掛載的$mount函數,此函數的實現與運行環境有關,在此只看web中的實現。

實現只有簡單的兩行,

1、判斷運行環境為瀏覽器,

2、調用工具方法查找到el對應的DOM節點,

3、mountComponent方法來實現掛載,

這里就涉及到了掛載之前的處理問題。

1、對於擁有render(JSX)函數的情況,組件可以直接掛載,

2、如果使用的是template,需要從中提取AST渲染方法(注意如果使用構建工具,最終會為我們編譯成render(JSX)形式,所以無需擔心性能問題),AST即抽象語法樹,它是對真實DOM結構的映射,可執行,可編譯,能夠把每個節點部分都編譯成vnode,組成一個有對應層次結構的vnode對象。

有了渲染方法,下一步就是更新DOM,注意並不是直接更新,而是通過vnode,於是涉及到了一個非常重要的概念。

 

四、虛擬dom

虛擬DOM技術是一個很流行的東西,現代前端開發框架vue和react都是基於虛擬DOM來實現的。

虛擬DOM技術是為了解決一個很重要的問題:瀏覽器進行DOM操作會帶來較大的開銷。

1、要知道js本身運行速度是很快的,

2、而js對象又可以很准確地描述出類似DOM的樹形結構,

基於這兩點前提,人們研究出一種方式,

通過使用js描述出一個假的DOM結構,每次數據變化時候,在假的DOM上分析數據變化前后結構差別,找出這個最小差別並且在真實DOM上只更新這個最小的變化內容,這樣就極大程度上降低了對DOM的操作帶來的性能開銷。

上面的假的DOM結構就是虛擬DOM,比對的算法成為diff算法,這是實現虛擬DOM技術的關鍵。

1、在vue初始化時,首先用JS對象描述出DOM樹的結構,

2、用這個描述樹去構建真實DOM,並實際展現到頁面中,

3、一旦有數據狀態變更,需要重新構建一個新的JS的DOM樹,

4、對比兩棵樹差別,找出最小更新內容,

5、並將最小差異內容更新到真實DOM上。

有了虛擬DOM,下面一個問題就是,什么時候會觸發更新,接下來要介紹的,就是vue中最具特色的功能--數據響應系統及實現。

 

五、數據綁定

vue.js的作者尤雨溪老師在知乎上一個回答中提到過自己創作vue的過程,最初就是嘗試實現一個類似angular1的東西,發現里面對於數據處理非常不優雅,於是創造性的嘗試利用ES5中的Object.defineProperty來實現數據綁定,於是就有了最初的vue。vue中響應式的數據處理方式是一項很有價值的東西。

vue官網上面其實有具體介紹,下面是一張官方圖片:

vue響應

響應實現的基本原理:

1、vue會遍歷此data中對象所有的屬性,

2、並使用Object.defineProperty把這些屬性全部轉為getter/setter,

3、而每個組件實例都有watcher對象,

4、它會在組件渲染的過程中把屬性記錄為依賴,

5、之后當依賴項的 setter被調用時,會通知watcher重新計算,從而致使它關聯的組件得以更新。

為什么vue不能在IE8以下運行?

因為IE8不支持ES5,所以用不了Object.defineProperty方法,又因為Object.defineProperty無法shim,所以vue不支持IE8及以下不支持ES5的瀏覽器。

 


免責聲明!

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



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