一、前言
最近一直在使用vue做專案,閒暇之餘查閱了一些關於vue實現原理的資料,一方面對所了解到的知識做個總結,另外一方面希望能對看到此文章的同學有所幫助。本文如有不足之處,還請過往的大佬批評指正。
二、vue實現原理概述
vue作為乙個前端漸進式的mvvm開發庫,將廣大的前端勞苦大眾從dom操作中解放出來;說到vue的實現原理,大體可分為三個要素:
1、資料的響應式,即vue可以監聽到資料的變化
2、模板引擎,模板引擎大家都應該不陌生,同之前使用的handlebars、arttemplate相似,都類似於html語法,不過可以寫一些邏輯在上面(資料繫結和事件繫結)
3、html的渲染,即通過模板引擎將資料渲染到頁面過程
第一步:解析模板成render函式
第二步:響應式開始監聽資料的變化
第三步:首次渲染頁面,顯示頁面,並繫結資料依賴和和事件
第四步:data的變化,觸發rerender,更新檢視的顯示
一下將通過解釋vue監聽資料的變化、模板繫結資料、資料渲染至頁面、實現只渲染資料改變部分dom這幾個部分進行講解
三、vue實現整體解析
1、vue如何實現對資料的監聽的?
說到vue對資料的監聽,不得不提到object.defineproperty,當前主流瀏覽器均支援此屬性,vue的資料雙向繫結及資料的監聽都是基於此實現的;請看下面**:
1 var obj ={};
2 var name = "mrgao"
3 object.defineproperty(obj, "name", ,
7 set: function(newval)
10 })
11 console.log(obj.name) // mrgao
12 obj.name = "mrbone";
13 console.log(obj.name) // mrbone
可以看到object.defineproperty傳了三個引數進去
第乙個引數為目標物件
第二個引數為要定義的屬性或方法名稱,(如果物件中不包含此屬性將此屬性新增到目標物件裡,vue中將data資料指向vm就是用的這裡,下面將詳細講解)
第三個引數為目標屬性的所擁有的特性
這三個引數為必填引數,另外對於第三個引數除get和set之外還有一些其它的屬性,在這裡提一下
value: 屬性的值
writable:屬性的值是否能被重寫,當設定為false的時候為唯讀,不能通過set進行重新賦值
configurable:是否可以設定他的其他屬性(value,writable)
enumerable:是否可以在object.keys或for...in中列舉出來
get和set上面例子已經提到
object.defineproperty在vue中的實現
我們知道在寫vue的時候都是可以通過this.*來讀取改變在data中定義的屬性,那麼這是怎麼實現的呢?這就是通過object.defineproperty將data中的屬性指向到vm中,即this就是之vm例項,參考一下實現**:
1 var data =;
6 var vm ={};
8 for(key indata) ,
14 set: function(newval)
17 })
18 })(key)
19 }
21 console.log(vm.name);
22 vm.name = "mrbone";
23 console.log(vm.name);
通過分析上面**可以看出vue通過object.defineproperty將data中的屬性指向vm例項,即this可以獲取data中的屬性
以上為vue資料響應式監聽的原理,接下來我們來看一下模板引擎的實現
2、vue模板引擎
說模板之前先來看下模板是什麼:
本質:字串
帶邏輯: 如v-if、v-for、v-model
特點:最終要通過js轉換成html**來顯示在頁面上
所以如果要讓有邏輯的模板顯示在頁面上,就需要通過js宣告乙個函式來處理這件事情,我們給它起個名字叫做render
通過都vue原始碼,可獲取關於render函式中的一些核心函式,下面通過乙個簡單的例子來做下介紹:
vm._updata(vnode) else{
vm.$el =vm.__patch__(prevvnode, vnode);
functionupdatecomponent() {
// vm._render為返回的虛擬dom
vm._update(vm._render());
3、資料渲染至頁面
將資料渲染進頁面,通過patch函式將虛擬dom轉換為真實dom結構頁面進行展示,渲染頁面的函式呼叫如下:
初次渲染
1、執行updatecomponent,執行vm._render()
2、執行render函式,會訪問到資料來源
3、相應式get方法監聽到訪問的資料來源執行updatecomponent,到patch()方法中的 vm.$el = vm.__patch__(vm.$el, vnode);
4、patch()將虛擬dom渲染成dom,初次渲染完成
修改屬性渲染
1、修改屬性,被響應式set監聽到
2、set中執行updatecomponent
3、updatecomponent重新執行vm._render()
4、生成vnode和舊的prevvnode,通過patch進行比較 vm.$el = vm.__patch__(prevvnode, vnode);
5、dom更新
四、小節
vue渲染頁面的流程 Vue中DOM渲染的過程
vue中dom渲染過程 1 響應式 監聽data屬性的getter setter 2 模板編譯 模板到render函式再到vnode。模板不是html,有指令 插值 js表示式,能夠實現迴圈 判斷。html是標籤語言,只有js才能實現迴圈判斷。因此,模板一定要轉化成js,即編譯模板。模板編譯為ren...
vue 渲染流程
1 dom 節點樹 高效的更新所有這些節點會是比較困難的,因為原生的dom節點屬性很多,渲染效能差。2 虛擬 dom 虛擬 dom 是我們對由 vue 元件樹建立起來的整個 vnode 樹的稱呼。vue 的模板實際是編譯成了render 函式。3 渲染流程 說明 1 模板template主要通過cr...
二 Vue 頁面渲染過程
上篇博文我們依葫蘆畫瓢已經將hello world 展現在介面上啦,但是是不是感覺新虛虛的,總覺得這麼多檔案,專案怎麼就啟動起來了呢?怎麼訪問到8080 埠就能進入到我們的首頁呢。整個的流程是怎麼樣的呢?我也是剛剛接觸,所以就會有這樣的困惑,所以這篇就簡單的理解一下專案頁面渲染的過程。我們上篇文章說...