一、前言
最近一直在使用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 ={};可以看到object.defineproperty傳了三個引數進去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
第乙個引數為目標物件
第二個引數為要定義的屬性或方法名稱,(如果物件中不包含此屬性將此屬性新增到目標物件裡,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 =;通過分析上面**可以看出vue通過object.defineproperty將data中的屬性指向vm例項,即this可以獲取data中的屬性6 var vm ={};
7 8 for(key indata) ,
14 set: function(newval)
17 })
18 })(key)
19 }
20 21 console.log(vm.name);
22 vm.name = "mrbone";
23 console.log(vm.name);
以上為vue資料響應式監聽的原理,接下來我們來看一下模板引擎的實現
2、vue模板引擎
說模板之前先來看下模板是什麼:
本質:字串
帶邏輯: 如v-if、v-for、v-model
特點:最終要通過js轉換成html**來顯示在頁面上
所以如果要讓有邏輯的模板顯示在頁面上,就需要通過js宣告乙個函式來處理這件事情,我們給它起個名字叫做render
通過都vue原始碼,可獲取關於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更新
四、小節
什麼是虛擬dom
Vue原始碼解析
原始碼位置 src core vdom patch.js updatechildren 作用 key的主要作用是高效的更新虛擬dom,原始碼中在patch的過程中,會執行patchvnode,patchvode過程中會執行updatechildren方法,會更新兩個新舊的子元素,通過key可以準確的...
flask Local原始碼流程解析
flask中local原始碼資料型別 首先明確 原始碼中要構造的資料型別數是這樣的 storage 其次原始碼用local類構造資料型別,然後又用localstack類,作用是操作local,讓我們使用起來更方便,localstack類中封裝了push方法,用來給呼叫local新增資料,pop方法取...
Vue 原始碼流程講解
模組分析vue原始碼,原始碼版本2.6.9 場景1 初始化vue例項,渲染到頁面,點選handlechangeweight方法 watch computed methods 1,data初始化,weight設定為響應式時,有乙個dep儲存依賴,在其他變數獲取當前weigth時,收集其他變數的watc...