從 jquery 的操作 dom 到 vue,react等框架的vdom實現,大大減少了dom的操作,提高效能。前端的刀耕火種,到現在的模組化,前端的內容每天都在發生著變化,每天都有著進步。前端的發展中我們繞不過乙個坎,那就是jquery,接下來我們會對比jquery和現在框架,來發現這些年前端取得的進步。
jquery與框架的區別:
jquery的本質還是操作dom,在處理dom的時候,也會導致資料和檢視層的不分離,資料中有dom的操作。這是jquery淘汰的乙個原因,因為他不符合基本的開閉原則(對修改關閉,對擴充套件開放)。
現在為我們熟知的框架,則是很好處理了這個問題。實現了資料和檢視的分離,解耦了檢視層和資料層,通過中間層來達到控制的目的,以資料驅動檢視,只關心資料的變化,dom的操作被封裝。
理解mvvm:
提到mvvm不得不提他的老前輩mvc(model + view + controller)
mvc:原型+檢視+控制器。使用者通過操作檢視。進而控制器去改變原型,進而改變檢視顯示。又或者使用者直接操作控制器改變原型,進而改變檢視層的顯示。jquer就是基於此設計的
在mvc的基礎上,前端創新的mvvm的vm(view model),介於view層和model層中間的vm層。他起著橋梁的作用。
檢視層通過事件來繫結模型層(資料層),資料層通過資料繫結來改變檢視層。vm就起著銜接的作用。我們就可以實現只關心資料的變化,不用去用控制器操作。
mvvm框架的三大要素:響應式,模板引擎,渲染
響應式:vue如何監聽data的變化?
模板引擎:vue的模板如何被解析,指令如何變化
渲染:vue的模板如何被渲染成html?以及渲染過程
響應式:
這裡的響應式是資料的響應式,資料的變化會被實時監聽。而vue實現data資料實時監聽的核心函式是object.defineproperty
這是es5中物件上的方法,他能實現對物件屬性get和set的監聽。
//響應式資料的核心函式,監聽資料改變
var vm = {};
var obj = ;
var key;
for (key in obj) ,
set: function(newval)
});})(key);
}
這裡我們還可以提出乙個問題,就是data中的資料如何掛載到vue例項上去的,其實也就是這個方法。在vue3.0版本以後,實現對資料的監聽換成了新的方法,運用了es6的語法(這裡不擴充套件)。
模板引擎:
模板是什麼:在vue中,是字串,他有邏輯,還嵌入了js變數。本質其實就是字串。邏輯對應的就是v-if,v-for等。他與html很像,但是區別很大,html是靜態的,html中沒有邏輯,沒有js變數。所以他可以按照瀏覽器指定好的規則去渲染,但是vue模板不能。他必須先解析。轉化為html,才能渲染到頁面。
這裡提到的解析,應該就知道我們需要借用js了,因為js是前端中圖靈完備的語言。(
因此,模板最重要是轉換成乙個js函式,在由js轉化成html(這裡指的是render函式(泛指渲染函式))
render函式執行完會返回乙個vnode(虛擬節點)
這裡我們就要提到前面的vdom(虛擬dom)。
vdom:
提問;vdom是什麼,為什麼會存在。vdom如何應用,核心api是什麼,
什麼是vdom和為什麼會存在:
用js模擬dom結構,dom變化的對比放在js層來做,存在的原因是提高重繪效能。
再次提出問題:為什麼dom操作是『昂貴』的。
我們建立乙個dom元素。然後遍歷這個dom元素,你會發現dom元素上有很多很多屬性。
最主要的原因還是,每次操作dom,會呼叫cpu和gpu。頁面的重排占用cpu的計算能力,頁面的重繪占用了gup的影象處理能力。
這裡還要說下gpu的分類。分為家用的和專業的。家用顯示卡也被稱為遊戲顯示卡。遊戲顯示卡他擅長於做貼圖,光影這些東西。專業顯示卡,擅長於畫圖,專業顯示卡的效能要比家用顯示卡好上幾十倍。
我們每次頁面的重排重繪都是相當於畫圖,而我們絕大部分的顯示卡都是家用顯示卡,所以在畫圖這方面效能並不好。
所以追尋到問題的本質,就是硬體的問題,導致操作dom顯得那麼『昂貴』。
明白了操作dom為什麼是『昂貴』的,就明白了vdom為什麼會存在。
vdom的應用:
介紹的是snabbdom
核心api:h函式和patch函式
h函式:定義乙個dom節點——vnode(模擬dom節點)
patch函式:接收兩個引數。初始的cantainer,和vnode
patch(container,vnode)//初次渲染
patch(vnode,newvnode) //再次渲染
patch函式就是乙個對比函式,這裡涉及到了diff演算法。(不是新東西。早在git命令中就有,對比兩個文字的差別)
vdom為何用diff演算法:
dom的操作是『昂貴』的,演算法的目的找出本次dom必須更新的節點來更新,其他節點不更新。這個過程就叫diff演算法。
render函式:
模板的所有資訊都包含在render函式中
函式執行完返回乙個vnode(模擬節點)
vue整個流程:四部曲
解析模板成render函式
內建用了with語法,使**簡潔
模板中所有的資訊都被render函式包含
模板中用到的data的屬性,都變成了js變數
模板中的v-model,v-if等都變成了js邏輯
render函式返回乙個vnode
響應式開始監聽
object.defineproperty核心函式實現監聽
將data屬性**到vue例項上(跟with用法有很大關係)
首次渲染,顯示頁面,且繫結依賴
初次渲染,執行updatacomponent,執行vm.render(vm是vue例項)
執行render函式,會訪問到vm.list和vm.title
執行updatacomponent,會走到vdom的pacth方法
pacth將vnode渲染成dom,初次渲染完成
會被響應式get方法監聽到
為何要監聽get,直接監聽set不行嗎?
data中有很多屬性,有些被用到,有些可能不被使用,被用到了會走get,不被用到不走get。沒有走get的屬性,set也沒必要關心,這樣就可以避免重複渲染了
data屬性變化,觸發rerender函式(二次渲染)
屬性修改,被set監聽到
set中執行updatacomponent(非同步方法)
updatacomponent重新執行vm._render()
生成的vnode和prevvnode,通過patch進行對比
渲染到html中
vue router的理解,以及實現原理
1早期的前端路由的實現就是基於 location.hash 來實現的。其實現原理很簡單,location.hash 的值就是 url 中 後面的內容。比如下面這個 它的 location.hash 的值為 search html5 提供了 history api 來實現 url 的變化。其中做最主要...
vue中雙資料繫結原理以及實現
熟悉vue的小夥伴應該熟悉vue中的v model的使用方法,他的作用就是來實心雙資料繫結的,那麼先在來說明一下雙資料繫結的原理 它的底層原理是由object.defineproperty實現的 作用 給乙個物件新增或者修改屬性,返回乙個物件 引數 引數一 目標物件 引數二 需要修改或新增的屬性 引...
紅黑樹原理解析以及Java實現
private static final boolean red true private static final boolean black false private node root 二叉查詢樹的根節點 結點資料結構 private class node 獲取整個二叉查詢樹的大小 retu...