国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

虛擬DOM

yanwei / 1311人閱讀

摘要:什么是虛擬舉例說明如果網(wǎng)頁中有一個(gè)表格,表頭是姓名,年級,分?jǐn)?shù)。即我們用虛擬的結(jié)構(gòu)替換需要處理的結(jié)構(gòu),對虛擬的進(jìn)行操作之后再進(jìn)行渲染,就成為了真實(shí)的數(shù)據(jù)。當(dāng)狀態(tài)變更的時(shí)候用修改后的新渲染的的對象和舊的虛擬對象作對比,記錄著兩棵樹的差異。

虛擬DOM

可以看看這個(gè)文章
如何理解虛擬DOM? - 戴嘉華的回答 - 知乎

https://www.zhihu.com/questio...

深度剖析:如何實(shí)現(xiàn)一個(gè) Virtual DOM 算法 #13

是什么 什么是DOM?

DOM 是 JavaScript 操作網(wǎng)頁的接口,全稱為“文檔對象模型”(Document Object Model)。它的作用是將網(wǎng)頁轉(zhuǎn)為一個(gè) JavaScript 對象,從而可以用腳本進(jìn)行各種操作(比如增刪內(nèi)容)。
DOM就是將網(wǎng)頁轉(zhuǎn)化為一個(gè)對象并提供操作這個(gè)對象接口(即操作這個(gè)對象的方法),所以可以通過DOM對網(wǎng)頁中的元素進(jìn)行操作。如對某個(gè)節(jié)點(diǎn)增加屬性,增加孩子,刪除等。
DOM就是網(wǎng)頁里你看得見的對應(yīng)的某個(gè)元素。

什么是虛擬DOM?

舉例說明:如果網(wǎng)頁中有一個(gè)表格,表頭是姓名,年級,分?jǐn)?shù)。如果我希望點(diǎn)擊姓名表格就按照字典序排序,點(diǎn)擊年級,按照年級從大到小排序等等操作,那么如果直接去操作DOM的話就很難實(shí)現(xiàn)。例如,我們刪除了一個(gè)DOM結(jié)點(diǎn),或者新增了一條數(shù)據(jù),那么重新進(jìn)行排序,就會(huì)刪除所有DOM然后重新渲染一遍DOM。如果數(shù)據(jù)很多的話,就會(huì)很浪費(fèi)資源,影響網(wǎng)頁的性能,可能會(huì)卡頓。

為什么會(huì)卡頓呢?是因?yàn)橐粋€(gè)節(jié)點(diǎn)元素實(shí)際上包含很多屬性方法,創(chuàng)建一個(gè)DOM就包含上百條數(shù)據(jù),加載上綁定的事件等。性能開銷很大。
我可以根據(jù)DOM結(jié)構(gòu),然后自己創(chuàng)建一個(gè)數(shù)據(jù)結(jié)構(gòu),自己創(chuàng)建的這個(gè)DOM和真實(shí)的DOM 是一一映射的。然后我們操作的時(shí)候就操作自己的數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)量很小,不管進(jìn)行排序或其他處理都會(huì)很迅速。處理好之后,再根據(jù)這個(gè)數(shù)據(jù)結(jié)構(gòu)把它變?yōu)檎鎸?shí)的DOM。
即我們用虛擬的DOM結(jié)構(gòu)替換需要處理的DOM結(jié)構(gòu),對虛擬的DOM 進(jìn)行操作之后再進(jìn)行渲染,就成為了真實(shí)的數(shù)據(jù)。

有什么用

這樣的好處是如果我們需要對DOM結(jié)點(diǎn)進(jìn)行改變,那么我們只需要查看我們自己創(chuàng)建的虛擬DOM,看看其中哪條數(shù)據(jù)發(fā)生了改變,然后修改虛擬DOM,并把它渲染成真實(shí)的數(shù)據(jù)即可。例如我們本來就有500條數(shù)據(jù),然后需要添加10條,那么我們只添加10條新的虛擬DOM,然后再把這10條虛擬DOM轉(zhuǎn)化為真實(shí)的DOM即可,不需要從新吧510跳全部重新渲染一遍。這樣性能會(huì)提升。

所謂的虛擬DOM實(shí)際上就是我們根據(jù)真實(shí)的DOM結(jié)構(gòu),創(chuàng)建一個(gè)和真實(shí)DOM映射的一個(gè)數(shù)據(jù)結(jié)構(gòu),然后對數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作,最后把這個(gè)數(shù)據(jù)結(jié)構(gòu)反映到真實(shí)的DOM中。

我們可以在邏輯上把這個(gè)數(shù)據(jù)結(jié)構(gòu)渲染成真實(shí)的DOM,他在數(shù)據(jù)結(jié)構(gòu)上和真實(shí)DOM是差不多的

舉個(gè)例子:我們可以使用一個(gè)數(shù)據(jù)結(jié)構(gòu)來映射DOM(用JS對象模擬DOM樹):
我們將節(jié)點(diǎn)用一個(gè)對象來表示,tag屬性表示他的種類,children屬性表示他擁有的兒子數(shù)組。那么:

這就是虛擬的DOM,體積很輕量,沒有所有的屬性和接口!用來操作的時(shí)候不需要耗費(fèi)很高的性能。
代碼如下:




  
  JS Bin




let nodesData = {
  tag: "div",
  children: [
    {
      tag: "p",
      children: [
        {
          tag: "span",
          children: [
            {
              tag: "#text",
              text: "xiedaimala.com"
            }
          ]
        }
      ]
    },
    {
      tag: "span",
        children: [
          {
            tag: "#text",
            text: "jirengu.com"
          }
        ]
    }
  ]
}

接下來我們只需要將這個(gè)虛擬的DOM渲染成真實(shí)的DOM就可以了,例如寫一個(gè)函數(shù)來渲染DOM。

function createElement (data){
    
}

舉例說明虛擬DOM的作用:
這時(shí)我們修改了DOM,例如我們將div中的p標(biāo)簽中span標(biāo)簽的內(nèi)容由xiedaimala.com修改為baidu.com,那么我們只需要修改我們創(chuàng)建的數(shù)據(jù)結(jié)構(gòu)中的span標(biāo)簽text那個(gè)屬性,然后將原來內(nèi)存中的nodesData與修改后的nodesData2進(jìn)行比較。例如:

let nodesData2 = {
  tag: "div",
  children: [
    {
      tag: "p",
      children: [
        {
          tag: "span",
          children: [
            {
              tag: "#text",
              text: "baidu.com"http://這里變了
            }
          ]
        }
      ]
    },
    {
      tag: "span",
        children: [
          {
            tag: "#text",
            text: "jirengu.com"
          }
        ]
    }
  ]
}

發(fā)現(xiàn)span標(biāo)簽的text內(nèi)容改變了,那么我們在修改真實(shí)DOM的時(shí)候不需要把所有的真實(shí)DOM的很多屬性和方法都檢索一遍,然后重新渲染一遍,而只需要重新渲染在虛擬DOM中比較出來的修改的部分,即只需要重新渲染text部分就可以了。

以下為
深度剖析:如何實(shí)現(xiàn)一個(gè) Virtual DOM 算法 #13文章中的一段解釋

既然原來 DOM 樹的信息都可以用 JavaScript 對象來表示,反過來,你就可以根據(jù)這個(gè)用 JavaScript 對象表示的樹結(jié)構(gòu)來構(gòu)建一棵真正的DOM樹。

之前的章節(jié)所說的,狀態(tài)變更->重新渲染整個(gè)視圖的方式可以稍微修改一下:用 JavaScript 對象表示 DOM 信息和結(jié)構(gòu),當(dāng)狀態(tài)變更的時(shí)候重新渲染這個(gè) JavaScript 的對象結(jié)構(gòu)。當(dāng)然這樣做其實(shí)沒什么卵用,因?yàn)檎嬲捻撁嫫鋵?shí)沒有改變。

但是可以用新渲染的對象樹去和舊的樹進(jìn)行對比,記錄這兩棵樹差異。記錄下來的不同就是我們需要對頁面真正的 DOM 操作,然后把它們應(yīng)用在真正的 DOM 樹上,頁面就變更了。這樣就可以做到:視圖的結(jié)構(gòu)確實(shí)是整個(gè)全新渲染了,但是最后操作DOM的時(shí)候確實(shí)只變更有不同的地方

如何實(shí)現(xiàn)

簡單實(shí)現(xiàn):

虛擬DOM渲染為真實(shí)DOM
/**
 * @author ruoyu
 * @description 虛擬 DOM Demo
 * @todo 暫時(shí)不考慮復(fù)雜情況
 */

class VNode {
  constructor(tag, children, text) {
    this.tag = tag
    this.text = text
    this.children = children
  }

  render() {
    if(this.tag === "#text") {
      return document.createTextNode(this.text)
    }
    let el = document.createElement(this.tag)
    this.children.forEach(vChild => {
      el.appendChild(vChild.render())
    })
    return el
  }
}

/*以上為ES6寫法,改為ES5寫法為:*/
/*******
function VNode() {
    this.tag = tag
    this.text = text
    this.children = children
}
VNode.prototype.render = function() {
    if(this.tag === "#text") {
      return document.createTextNode(this.text)
    }
    let el = document.createElement(this.tag)
    this.children.forEach(vChild => {
      el.appendChild(vChild.render())//遞歸生成子節(jié)點(diǎn)
    })
    return el
}  
******
這幾句代碼的作用是將js對象表示的虛擬DOM渲染為真實(shí)的DOM
*/

/*這個(gè)函數(shù)的作用是傳入幾個(gè)參數(shù),然后返回對象*/
function v(tag, children, text) {
  if(typeof children === "string") {
    text = children
    children = []
  }
  return new VNode(tag, children, text)
}


/*  這里是js對象虛擬dom的數(shù)據(jù)結(jié)構(gòu)

let nodesData = {
  tag: "div",
  children: [
    {
      tag: "p",
      children: [
        {
          tag: "span",
          children: [
            {
              tag: "#text",
              text: "xiedaimala.com"
            }
          ]
        }
      ]
    },
    {
      tag: "span",
        children: [
          {
            tag: "#text",
            text: "jirengu.com"
          }
        ]
    }
  ]
}

 */

/*使用v函數(shù)將幾個(gè)參數(shù)轉(zhuǎn)化為對象并返回*/
let vNodes = v("div", [
      v("p", [
        v("span", [ v("#text", "xiedaimala.com") ] )
        ]
      ),
      v("span", [
        v("#text",  "jirengu.com")
        ])
    ]
  )
/*渲染為真實(shí)的DOM*/
console.log(vNodes) /*下方有打印的結(jié)果*/
console.log(vNodes.render())


我們看一下打印的結(jié)果

DOM數(shù)據(jù)更新

以下僅為簡單實(shí)現(xiàn),是為了理解原理,實(shí)際上要想做到很完美的虛擬DOM,需要考慮很多

function patchElement(parent, newVNode, oldVNode, index = 0) {
  if(!oldVNode) {//如果沒有,直接創(chuàng)建新的DOM,例如patchElement(root, vNodes1)
    parent.appendChild(newVNode.render())
  } else if(!newVNode) {//刪除DOM的操作,例如patchElement(root)
    parent.removeChild(parent.childNodes[index])
  } else if(newVNode.tag !== oldVNode.tag || newVNode.text !== oldVNode.text)//替換(修改)DOM操作,例如兩個(gè)VNode比較簡單,然后互相比較
 {
    parent.replaceChild(newVNode.render(), parent.childNodes[index])
  }  else {//遞歸替換孩子DOM,遞歸比較
    for(let i = 0; i < newVNode.children.length || i < oldVNode.children.length; i++) {
      patchElement(parent.childNodes[index], newVNode.children[i], oldVNode.children[i], i)
    }
  }
}



let vNodes1 = v("div", [
      v("p", [
        v("span", [ v("#text", "xiedaimala.com") ] )
        ]
      ),
      v("span", [
        v("#text",  "jirengu.com")
        ])
    ]
  )

let vNodes2 = v("div", [
      v("p", [
        v("span", [ 
          v("#text", "xiedaimala.com") 
          ] )
        ]
      ),
      v("span", [
        v("#text",  "jirengu.coms"),
        v("#text",  "ruoyu")
        ])
    ]
  )
const root = document.querySelector("#root")

patchElement(root, vNodes1)//創(chuàng)建新的DOM,
patchElement(root)//刪除DOM的操作
patchElement(root, vNodes2,vNodes1)//替換(修改)DOM操作

以上只是簡單實(shí)現(xiàn)!有很多bug

總結(jié)

問:說說虛擬DOM:
當(dāng)我們修改真正的DOM樹的時(shí)候,因?yàn)镈OM中元素節(jié)點(diǎn)有許多的屬性和方法,當(dāng)DOM中節(jié)點(diǎn)過多時(shí)往往需要消耗很大的性能。
解決方法是:使用js對象來表示DOM樹的信息和結(jié)構(gòu),這個(gè)js對象可以構(gòu)建一個(gè)真正的DOM樹。當(dāng)狀態(tài)變更的時(shí)候用修改后的新渲染的的js對象和舊的虛擬DOM js對象作對比,記錄著兩棵樹的差異。把差別反映到真實(shí)的DOM 結(jié)構(gòu)上最后操作真正的DOM的時(shí)候只操作有差異的部分就可以了

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/98060.html

相關(guān)文章

  • 虛擬Dom詳解 - (一)

    摘要:為此也做了一些學(xué)習(xí)簡單的侃一侃虛擬到底是什么虛擬詳解二什么是虛擬虛擬首次產(chǎn)生是框架最先提出和使用的,其卓越的性能很快得到廣大開發(fā)者的認(rèn)可,繼之后也在其核心引入了虛擬的概念。所謂的虛擬到底是什么也就是通過語言來描述一段代碼。 隨著Vue和React的風(fēng)聲水起,伴隨著諸多框架的成長,虛擬DOM漸漸成了我們經(jīng)常議論和討論的話題。什么是虛擬DOM,虛擬DOM是如何渲染的,那么Vue的虛擬Dom...

    ashe 評論0 收藏0
  • 虛擬DOM

    摘要:什么是虛擬舉例說明如果網(wǎng)頁中有一個(gè)表格,表頭是姓名,年級,分?jǐn)?shù)。即我們用虛擬的結(jié)構(gòu)替換需要處理的結(jié)構(gòu),對虛擬的進(jìn)行操作之后再進(jìn)行渲染,就成為了真實(shí)的數(shù)據(jù)。當(dāng)狀態(tài)變更的時(shí)候用修改后的新渲染的的對象和舊的虛擬對象作對比,記錄著兩棵樹的差異。 虛擬DOM 可以看看這個(gè)文章如何理解虛擬DOM? - 戴嘉華的回答 - 知乎 https://www.zhihu.com/questio... 深度剖...

    alin 評論0 收藏0
  • react虛擬dom機(jī)制與diff算法

    摘要:的一個(gè)突出特點(diǎn)是擁有極速地渲染性能。該功能依靠的就是研發(fā)團(tuán)隊(duì)弄出的虛擬機(jī)制以及其獨(dú)特的算法。在的算法下,在同一位置對比前后節(jié)點(diǎn)只要發(fā)現(xiàn)不同,就會(huì)刪除操作前的節(jié)點(diǎn)包括其子節(jié)點(diǎn),替換為操作后的節(jié)點(diǎn)。 React的一個(gè)突出特點(diǎn)是擁有極速地渲染性能。該功能依靠的就是facebook研發(fā)團(tuán)隊(duì)弄出的虛擬dom機(jī)制以及其獨(dú)特的diff算法。下面簡單解釋一下react虛擬dom機(jī)制和diff算法的實(shí)現(xiàn)...

    jzman 評論0 收藏0
  • 什么是虛擬DOM

    摘要:虛擬之上延伸了什么概念由于是虛擬,延伸了的是聲明式的,我們不需要具體操作。虛擬沒有解決什么問題目前自己了解的,虛擬無非是對象的表示。參考鏈接官網(wǎng)怎么寫你自己的虛擬 虛擬DOM的內(nèi)涵和外延? 內(nèi)涵 虛擬DOM它是真實(shí)DOM的內(nèi)存表示,一種編程概念,一種模式。它會(huì)和真實(shí)的DOM同步,比如通過ReactDOM這種庫,這個(gè)同步的過程叫做調(diào)和(reconcilation)。 描述HTML標(biāo)簽,使...

    hosition 評論0 收藏0
  • 虛擬Dom詳解 - (二)

    摘要:第一篇文章中主要講解了虛擬基本實(shí)現(xiàn),簡單的回顧一下,虛擬是使用數(shù)據(jù)描述的一段虛擬節(jié)點(diǎn)樹,通過函數(shù)生成其真實(shí)節(jié)點(diǎn)。并添加到其對應(yīng)的元素容器中。在創(chuàng)建真實(shí)節(jié)點(diǎn)的同時(shí)并為其注冊事件并添加一些附屬屬性。 第一篇文章中主要講解了虛擬DOM基本實(shí)現(xiàn),簡單的回顧一下,虛擬DOM是使用json數(shù)據(jù)描述的一段虛擬Node節(jié)點(diǎn)樹,通過render函數(shù)生成其真實(shí)DOM節(jié)點(diǎn)。并添加到其對應(yīng)的元素容器中。在創(chuàng)建...

    sevi_stuo 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<