vue.js框架原理浅析
vue.js是一個非常優(yōu)秀的前端開發(fā)框架,不是我說的,大家都知道。
首先我現(xiàn)在的能力,獨立閱讀源碼還是有很大壓力的,所幸vue寫的很規(guī)范,通過方法名基本可以略知一二,里面的原理不懂的地方多方面查找資料,本文中不規(guī)范不正確的地方歡迎指正,學(xué)生非常愿意接受各位前輩提出寶貴的建議和指導(dǎo)。
使用vue的版本是v2.5.13,采用了flow作為類型管理工具,關(guān)于flow相關(guān)內(nèi)容選擇性忽略了,不考慮類型系統(tǒng),只考慮實現(xiàn)原理,寫下這篇文章。
本文大概涉及到vue幾個核心的地方:vue實例化,虛擬DOM,模板編譯過程,數(shù)據(jù)綁定。
二、vue實例化
研究vue的實例化就要研究_init方法,此方法定義在src/core/instance/init.js下的initMixin中,里面是對vue實例即vm的處理。其中包括開發(fā)環(huán)境下的代理配置等一些列處理,并處理了傳遞給構(gòu)造函數(shù)的參數(shù)等,重點在一系列方法
initLifecycle(vm)initEvents(vm)initRender(vm)callHook(vm, 'beforeCreate')initInjections(vm) // resolve injections before data/propsinitState(vm)initProvide(vm) // resolve provide after data/propscallHook(vm, 'created')復(fù)制代碼初始化生命周期,初始化事件,初始化渲染,觸發(fā)執(zhí)行beforeCreate生命周期方法,初始化data/props數(shù)據(jù)監(jiān)聽,觸發(fā)執(zhí)行created生命周期方法。
對應(yīng)到生命周期示例圖,created方法執(zhí)行結(jié)束,接下來判斷是否傳入掛載的el節(jié)點,如果傳入的話此時就會通過$mount函數(shù)把組件掛載到DOM上面,整個vue構(gòu)造函數(shù)就執(zhí)行完成了。以上是vue對象創(chuàng)建的基本流程。
掛載的$mount函數(shù),此函數(shù)的實現(xiàn)與運行環(huán)境有關(guān),在此只看web中的實現(xiàn)。
實現(xiàn)只有簡單的兩行,
1、判斷運行環(huán)境為瀏覽器,
2、調(diào)用工具方法查找到el對應(yīng)的DOM節(jié)點,
3、mountComponent方法來實現(xiàn)掛載,
這里就涉及到了掛載之前的處理問題。
1、對于擁有render(JSX)函數(shù)的情況,組件可以直接掛載,
2、如果使用的是template,需要從中提取AST渲染方法(注意如果使用構(gòu)建工具,最終會為我們編譯成render(JSX)形式,所以無需擔心性能問題),AST即抽象語法樹,它是對真實DOM結(jié)構(gòu)的映射,可執(zhí)行,可編譯,能夠把每個節(jié)點部分都編譯成vnode,組成一個有對應(yīng)層次結(jié)構(gòu)的vnode對象。
有了渲染方法,下一步就是更新DOM,注意并不是直接更新,而是通過vnode,于是涉及到了一個非常重要的概念。
虛擬DOM技術(shù)是一個很流行的東西,現(xiàn)代前端開發(fā)框架vue和react都是基于虛擬DOM來實現(xiàn)的。
虛擬DOM技術(shù)是為了解決一個很重要的問題:瀏覽器進行DOM操作會帶來較大的開銷。
1、要知道js本身運行速度是很快的,
2、而js對象又可以很準確地描述出類似DOM的樹形結(jié)構(gòu),
基于這兩點前提,人們研究出一種方式,
通過使用js描述出一個假的DOM結(jié)構(gòu),每次數(shù)據(jù)變化時候,在假的DOM上分析數(shù)據(jù)變化前后結(jié)構(gòu)差別,找出這個最小差別并且在真實DOM上只更新這個最小的變化內(nèi)容,這樣就極大程度上降低了對DOM的操作帶來的性能開銷。
上面的假的DOM結(jié)構(gòu)就是虛擬DOM,比對的算法成為diff算法,這是實現(xiàn)虛擬DOM技術(shù)的關(guān)鍵。
1、在vue初始化時,首先用JS對象描述出DOM樹的結(jié)構(gòu),
2、用這個描述樹去構(gòu)建真實DOM,并實際展現(xiàn)到頁面中,
3、一旦有數(shù)據(jù)狀態(tài)變更,需要重新構(gòu)建一個新的JS的DOM樹,
4、對比兩棵樹差別,找出最小更新內(nèi)容,
5、并將最小差異內(nèi)容更新到真實DOM上。
有了虛擬DOM,下面一個問題就是,什么時候會觸發(fā)更新,接下來要介紹的,就是vue中最具特色的功能--數(shù)據(jù)響應(yīng)系統(tǒng)及實現(xiàn)。
vue.js的作者尤雨溪老師在知乎上一個回答中提到過自己創(chuàng)作vue的過程,最初就是嘗試實現(xiàn)一個類似angular1的東西,發(fā)現(xiàn)里面對于數(shù)據(jù)處理非常不優(yōu)雅,于是創(chuàng)造性的嘗試利用ES5中的Object.defineProperty來實現(xiàn)數(shù)據(jù)綁定,于是就有了最初的vue。vue中響應(yīng)式的數(shù)據(jù)處理方式是一項很有價值的東西。
vue官網(wǎng)上面其實有具體介紹,下面是一張官方圖片:
響應(yīng)實現(xiàn)的基本原理:
1、vue會遍歷此data中對象所有的屬性,
2、并使用Object.defineProperty把這些屬性全部轉(zhuǎn)為getter/setter,
3、而每個組件實例都有watcher對象,
4、它會在組件渲染的過程中把屬性記錄為依賴,
5、之后當依賴項的 setter被調(diào)用時,會通知watcher重新計算,從而致使它關(guān)聯(lián)的組件得以更新。
為什么vue不能在IE8以下運行?
因為IE8不支持ES5,所以用不了Object.defineProperty方法,又因為Object.defineProperty無法shim,所以vue不支持IE8及以下不支持ES5的瀏覽器。
總結(jié)
以上是生活随笔為你收集整理的vue.js框架原理浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Typescript04---模块、命名
- 下一篇: Hadoop学习(二)——MapRedu