虛擬DOM和Render函式

2022-06-23 19:45:13 字數 2964 閱讀 5224

虛擬dom(下面簡化稱為vnode)簡而言之 ,就是用js去描述一個dom節點樹,而dom變化的對比,都放在js層來做。

傳統的dom節點,是這樣的

>

classname='text'>寫個啥內容

>

vnode是長這樣的

,  //屬性鍵值對

children:, //子節點

key:undefined, //節點的唯一值

...

}

為什麼需要vnode?

這裡,我們來引入一個傳統的操作dom栗子。

var arr = [1,2,3,4]

function render(data)

var ul= createelement('ui')

data.foreach((elem)=>)

return ul

}render(arr)

輸出列印的結果是:

但是這樣操作dom的結果,當專案越大,頁面互動越複雜,頻繁的去操作dom,會導致頁面卡頓,效能差,如何去減少dom操作是效能優化的一個關鍵點。

千呼萬喚的,vnode可以解決這樣的問題!!!

vnode是vue和react的核心。將dom對比操作放在js層,提高效率。

如何使用vnode?
首先vdom的兩個核心api
h是指hyperscript,一種可以通過js來建立html的庫。

>

classname='text'>寫個啥內容

>

//經過babel編譯,然後將它們傳遞給h函式呼叫

h( 'div',

null,

h('p',,'寫個啥內容啊')

)//react的react.createelement函式的作用就跟這裡的h函式一樣,結果是為了獲得一個vnode,虛擬節點

h函式輸出的元素是一個dom節點的js物件,類似這樣

,

'children':[...],

'key':undefined,

...}

h函式結束後,會呼叫render函式啦!!!

前面我們提到了jsx是如何轉換為虛擬dom的js物件,那麼虛擬dom又是如何轉為真實的dom?

這裡需要思考兩個問題:

寫過react的人都知道,我們每個元件中有且只有一個render方法

//class方式建立的元件

class home extends react.component

}// 函式申明建立的元件

function page()

以上的**栗子容易看出,無論是class方式還是函式申明方式建立出來的元件,返回的有且只有一個頂點節點。呼叫render方法,可以將react元素渲染到真實的dom中。

在元件例項化和存在期時會執行render。

從下圖中可以看出:

同樣,在purecomponent中,只接受props和state引數,如果props和state沒有改變,purecomponent不會重渲染,可以一定程度上減少了render帶來的消耗。

前面提到,react的核心虛擬dom可以講真實的dom節點以obj物件的形式來表示,通過對比新舊的obj物件的差異,更改頁面相對應的變化節點。而react.render實際上就相當於是vdom裡面的path函式,path函式接收兩個引數。

以下例子,建立一個節點的實現思路(簡易的)

var vnode

function render(data),

children:[…]}*/

if(vnode)else

// 將舊節點儲存起來,便於下次新節點的新舊對比

vnode = newvnode

}

第一次渲染是如何進行?

path(container,newvnode)

// 建立一個真實節點

function createelement(vnode)

var elem = document.createelement(tag) // 建立一個真實的dom節點

for(attrname in attrs)

}children.foreach(function(childvode))

return elem

}

再次渲染是如何進行?

path(vnode,newvnode)

//更新渲染,通過對比新舊vnode,更新節點樹

function updatechildren (vnode,newvnode)

if(child.tag === newchild.tag)else })}

path(container,vnode)和path(vnode,newvnode)的實現也是diff演算法的一個實現過程,通過呼叫createelement和updatechildren方法讓頁面上的節點建立和更新。

當然,真正的diff演算法是非常複雜的。

這一節的主要講的render函式在react中的一個工作過程,減少和控制不必要的重複渲染可以有效的提高頁面效能。

DOM和BOM

dom全稱 document object model 文件物件模型 通過dom將html文件轉化為物件模型,操作整個網頁。dom分為htm...

Refs 和 DOM

在常規的 react 資料流中,props 是父元件與子元件互動的唯一方式。要修改子元素,你需要用新的 props 去重新渲染子元素。然而,在少數情況下,你需要在常規資料流外強制修改子元素。被修改的子元素可以是 react 元件例項,或者是一個 dom 元素。在這種情況下,react 提供瞭解決辦法...

DOM 3 DOM核心和DOM2 HTML 2

由於繼承擴充套件的關係,dom中大部分物件會有node物件的屬性和方法,其中包括 dom2核心中規定的每種nodetype預期的nodena...