虚拟dom比对原理

Posted jlfw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟dom比对原理相关的知识,希望对你有一定的参考价值。

dom对比步骤

1.用js对象来表达dom结构

tagName 标签名
props 元素属性
key 唯一标识
children 子元素,格式和父元素一样
count 有几个子元素,用于计算当前元素的索引,处于整个dom中的第几个,方便dom操作

原js对象

{
    "tagName": "div",
    "props": {
        "id": "container"
    },
    "children": [
        {
            "tagName": "h1",
            "props": {
                "style": "color:red"
            },
            "children": [
                "simple virtual dom"
            ],
            "count": 1
        },
        {
            "tagName": "p",
            "props": {},
            "children": [
                "hello world"
            ],
            "count": 1
        },
        {
            "tagName": "ul",
            "props": {},
            "children": [
                {
                    "tagName": "li",
                    "props": {},
                    "children": [
                        "item #1"
                    ],
                    "count": 1
                },
                {
                    "tagName": "li",
                    "props": {},
                    "children": [
                        "item #2"
                    ],
                    "count": 1
                }
            ],
            "count": 4
        }
    ],
    "count": 9
}

2.原js对象渲染成dom结构

<div id="container">
    <h1 style="color: red;">simple virtual dom</h1>
    <p>hello world</p>
    <ul>
        <li>item #1</li>
        <li>item #2</li>
    </ul>
</div>

3.修改原js对象

{
    "tagName": "div",
    "props": {
        "id": "container2"
    },
    "children": [
        {
            "tagName": "h5",
            "props": {
                "style": "color:red"
            },
            "children": [
                "simple virtual dom"
            ],
            "count": 1
        },
        {
            "tagName": "p",
            "props": {},
            "children": [
                "hello world2"
            ],
            "count": 1
        },
        {
            "tagName": "ul",
            "props": {},
            "children": [
                {
                    "tagName": "li",
                    "props": {},
                    "children": [
                        "item #1"
                    ],
                    "count": 1
                },
                {
                    "tagName": "li",
                    "props": {},
                    "children": [
                        "item #2"
                    ],
                    "count": 1
                },
                {
                    "tagName": "li",
                    "props": {},
                    "children": [
                        "item #3"
                    ],
                    "count": 1
                }
            ],
            "count": 6
        }
    ],
    "count": 11
}

4.对比哪些节点被修改
type 类型,0为标签名改变,1为子元素改变(删除或添加),2为属性改变,3为内容改变
key 对象第一层中key值表示索引,原dom中第几个元素发生变化

{
    "0": [
        {
            "type": 2,
            "props": {
                "id": "container2"
            }
        }
    ],
    "1": [
        {
            "type": 0,
            "node": {
                "tagName": "h5",
                "props": {
                    "style": "color:red"
                },
                "children": [
                    "simple virtual dom"
                ],
                "count": 1
            }
        }
    ],
    "4": [
        {
            "type": 3,
            "content": "hello world2"
        }
    ],
    "5": [
        {
            "type": 1,
            "moves": [
                {
                    "index": 2,
                    "item": {
                        "tagName": "li",
                        "props": {},
                        "children": [
                            "item #3"
                        ],
                        "count": 1
                    },
                    "type": 1
                }
            ]
        }
    ]
}

5.渲染修改后的js对象

a.标签名改变,直接重新渲染整个元素,包括元素下的子元素
b.子元素改变,该删除的删除,该添加的添加(针对列表框架有一套自己的计算方法,可以自行百度去研究)
c.属性改变,操作对应元素的属性
d.内容改变,操作对应元素的内容

<div id="container2">
    <h5 style="color: red;">simple virtual dom</h5>
    <p>hello world2</p>
    <ul>
        <li>item #1</li>
        <li>item #2</li>
        <li>item #3</li>
    </ul>
</div>

技术图片

以上是关于虚拟dom比对原理的主要内容,如果未能解决你的问题,请参考以下文章

Vue2.x源码系列08Diff算法原理

React篇(010)-为什么虚拟 dom 会提高性能?

通过编写简易虚拟DOM,来学习虚拟DOM 的原理

react中性能优化的点

虚拟DOM详解

虚拟DOM详解