国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - React - react中的虛擬dom和diff算法詳解

react中的虛擬dom和diff算法詳解

2022-03-05 20:49家里有只豬 React

這篇文章主要介紹了react中的虛擬dom和diff算法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

虛擬DOM的作用

首先我們要知道虛擬dom的出現是為了解決什么問題的,他解決我們平時頻繁的直接操作DOM效率低下的問題。那么為什么我們直接操作DOM效率會低下呢?

比如我們創建一個div,我們可以在控制臺查看一下這個div上自帶或者繼承了很多屬性,尤其是我們使用js操作DOM的時候,我們的DOM本身就很復雜,js的操作也會占用很多時間,但是我們控制不了DOM元素本身,因此虛擬DOM解決的是js操作DOM這一層面,其實解決的是減少了操作dom的次數

簡單實現虛擬DOM

虛擬DOM,見名知意,就是假的DOM,我們真實的DOM掛載在頁面上的,而我們的虛擬DOM則是在內存中的。這個就需要我們把真實的DOM抽象成一個對象放在內存中。這個對象就可以是如下類型:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var element = {
      tagName: 'div',
      props: {
        class: 'box'
      },
      children: {
        {
          tagName: 'p',
          props: {
            class: 'p1'
          },
          children: ['我是p1']
        },
         {
          tagName: 'p',
          props: {
            class: 'p2'
          },
          children: ['我是p2']
        },
        {
          tagName: 'p',
          props: {
            class: 'p3'
          },
          children: ['我是p3']
        },
      }
    }

我們想要構造出這樣的對象可以自己封裝一個構造函數如下:

?
1
2
3
4
5
function Element(tagName, props, children) {
    this.tagName = tagName
    this.props = props
    this.children = children
}

有了這個對象,我們需要把這個虛擬DOM渲染到真實DOM上,可以寫出如下方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Element.prototype.render = function () {
    const { tagName, props, children } = this
    var el = document.createElement(tagName)
    for (key in props) {
        el.setAttribute(key, props[key])
    }
    children.forEach((item) => {
        const childEl = (item instanceof Element) ?
              item.render() :
        document.createTextNode(item)
        el.appendChild(childEl)
    })
    return el
}

最后我們可以new出這個對象調用render()方法然后appendChild到body中就好了:

?
1
2
3
4
5
6
7
8
let virtualDom = new Element('div', { class: 'box' }, [
    new Element('p', { class: 'p1' }, ['我是p1']),
    new Element('p', { class: 'p2' }, ['我是p2']),
    new Element('p', { class: 'p3' }, ['我是p3']),
])
 
let a = virtualDom.render()
document.body.appendChild(a)

diff算法

首先我們先了解一下diff算法的作用

如果我們的虛擬dom發生了變化,我們的內存中又會產生新的虛擬DOM,如果我們直接用這個新的虛擬DOM結構的話,又會導致很多重復的渲染,因此 這個時候diff算法的作用就體現了出來,diff通過比較新舊兩個虛擬DOM樹,找出差異,并且記錄下來,然后把記錄的差異應用到真實的DOM樹上。

原理:

diff算法通過對新舊兩顆樹進行深度優先遍歷,每一個節點都加一個唯一的標識。

這個過程分為2步

  • 找出兩個樹的差異,并記錄在一個偽數組里。
  • 把這些不同應用到真實的DOM樹上

對于dom的操作基本可化為4種類型

  • 對節點的刪除,移動,添加子節點
  • 更換節點標簽
  • 對于文本節點,修改節點文本
  • 修改節點props

下面會用偽代碼的形式大致過一下這個流程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// diff 函數,對比兩棵樹
function diff(oldTree, newTree) {
    var patchs = {};  // 偽數組,記錄差異
    //  對4種節點做錯判斷
    dfWork(oldTree, newTree, patchs, index)
 
    return patchs
 
}
function dfWork(oldTree, newTree, patchs, index) {
    let currentPatch = []
 
    if (1) { // 對節點的刪除
        currentPatch.push()
    } else if (3) { // 對節點的文本的更換
        currentPatch.push()
 
    } else { // 修改節點的props 對children的檢查
        // 對props作diff算法,把變化記錄到patchs中。
        currentPatch.push({ type: patch.PROPS, props: propsPatches })
        // 然后需要對子節點作diff算法
        diffChildren(oldNode.children, newNode.children, index, patches, currentPatch)
    }
}
function diffChildren(oldChildren, newChildren, index, patches, currentPatch) {
 
    // 對子節點作diff算法,遍歷子節點,遞歸調用dfWork,做差異得到patchs
 
}
// 把變化應用在真實的DOM樹上
function patch(node, patchs) {
    // node為老的DOM樹,patchs變化。
    // 我們會遍歷這個patchs,并且把node和patch對應上,
}
function applyPatch(node, patchs) {
    // 應為每個節點可能有多個變化,所以也需要遍歷
    switch (patchs.type) {
        case REPLACE: // 節點替換
            // node.render()
            break;
        case REORDER:  // 節點的移動刪除新增子節點。
 
            break;
        case PROPS:
            // setProps
            break;
        case TEXT: // 對節點文本的修改
            // node.nodeValue
            break;
 
        default:
            break;
    }
}

參考文檔:深度剖析:如何實現一個 Virtual DOM 算法 作者:livoras,內置源碼。

到此這篇關于react中的虛擬dom和diff算法的文章就介紹到這了,更多相關react虛擬dom和diff算法內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/qq_44983621/article/details/115733067

延伸 · 閱讀

精彩推薦
  • Reactreact中常見hook的使用方式

    react中常見hook的使用方式

    這篇文章主要介紹了react中常見hook的使用方式與區別,幫助大家更好的理解和學習使用react,感興趣的朋友可以了解下...

    一顆冰淇淋8902022-02-25
  • React詳解React中共享組件邏輯的三種方式

    詳解React中共享組件邏輯的三種方式

    這篇文章主要介紹了詳解React中共享組件邏輯的三種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    Null20203692022-01-12
  • ReactReact中useRef的具體使用

    React中useRef的具體使用

    這篇文章主要介紹了React中useRef的具體使用,它可以用來獲取組件實例對象或者是DOM對象,除此之外還有哪些用法,就一起來了解一下...

    Meskjei6342022-02-28
  • React詳解對于React結合Antd的Form組件實現登錄功能

    詳解對于React結合Antd的Form組件實現登錄功能

    這篇文章主要介紹了詳解對于React結合Antd的Form組件實現登錄功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需...

    浮生離夢6622022-02-23
  • ReactReact+Antd 實現可增刪改表格的示例

    React+Antd 實現可增刪改表格的示例

    這篇文章主要介紹了React+Antd實現可增刪改表格的示例,幫助大家更好的理解和學習使用React,感興趣的朋友可以了解下...

    用戶3202285797825912022-02-24
  • React從框架作者角度聊:React調度算法的迭代過程

    從框架作者角度聊:React調度算法的迭代過程

    React內部最難理解的地方就是「調度算法」,不僅抽象、復雜,還重構了一次??梢哉f,只有React團隊自己才能完全理解這套算法。既然這樣,那本文嘗試從...

    魔術師卡頌8172022-01-10
  • React淺談React Router關于history的那些事

    淺談React Router關于history的那些事

    這篇文章主要介紹了淺談React Router關于history的那些事,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們...

    這是上帝的杰作12032022-02-23
  • ReactReact三大屬性之props的使用詳解

    React三大屬性之props的使用詳解

    這篇文章主要介紹了React三大屬性之props的使用詳解,幫助大家更好的理解和學習使用React,感興趣的朋友可以了解下...

    xiaoznz10002022-03-02
主站蜘蛛池模板: 成人免费视屏 | 免费一区| 91av免费在线观看 | 国产精品99久久久久久动医院 | 日韩中文一区二区三区 | 免费观看全黄做爰大片国产 | 欧美日韩免费在线 | 欧美日韩国产一区二区 | 国产精品久久久久久久久 | 午夜视频在线 | 欧美日韩在线观看一区二区 | 在线播放91| 欧美高清免费 | 国产精品一区二区三 | 伦理午夜电影免费观看 | 亚洲国产高清高潮精品美女 | 精品无码久久久久久久动漫 | 久久久精品久久久 | 青青草91在线视频 | 综合久久99| 精品国产不卡一区二区三区 | 日韩有码在线播放 | 欧美亚洲| 国产精品成av人在线视午夜片 | 天天爱天天草 | 久久久免费视频看看 | 91性高湖久久久久久久久网站 | 中文字幕一区在线观看视频 | 亚洲午夜电影在线 | 国产精品亚洲精品 | 日韩av在线中文字幕 | 国产精品视频久久 | 蜜桃免费一区二区三区 | 精品欧美乱码久久久久久1区2区 | 国产精品国产精品国产专区不卡 | 久久国产99 | 婷婷激情五月 | 亚洲高清在线观看 | 久久久久一区二区 | 欧美精品一二三 | 久久国产精品免费 |