浅谈 虚拟Dom (VitrualDom)
本文将简单为大家讲解虚拟Dom与diff算法
众所周知,真实的dom就是浏览器渲染而成的一棵真实的dom树。然而,当我们每一次对这一棵真实的dom树进行修改的时候,我们的浏览器并不会去寻找你到底对这棵真实的dom树哪里进行修改了,浏览器只会直接砍掉这棵真实的dom树,再把你修改好的dom重新渲染一棵。 为了避免每一次修改同一个dom树,浏览器每一次都”砍树“的暴力拆迁,尽量减少Dom操作的性能开销。由此,虚拟dom应运而生。我们使用的Vue、React等框架就采用了虚拟dom。
-
什么是虚拟dom
![]()
虚拟dom其实是里面内存型对象(js内存对象)属于内存数据,是真实dom的一层映射。一般用在循环里面,防止出错,并且加快效率。简单来说,虚拟dom就是通过一些特别的步骤来避免整棵 DOM 树变更。步骤具体如下:
-
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
-
当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较(使用diff算法),记录两棵树差异
-
把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了
![]()
-
-
实现虚拟dom
- 内存中生成一颗虚拟dom树
//我们将要进行的数据变化放在arr里面 var data = { arr:[] } //内存中生成一颗虚拟dom树 var vDom = { tag:"div",//<div></div> attr:{ id:"content"//<div id="content"></div> }, children:[ {tag:"p",content:1},//<p>1</p> {tag:"ul",attrs:{className:"list-group"}},//<ul class="list-group"></ul> {tag:"div",content:2},//<div>2</div> ] }
- 将内存中的虚拟dom树初始化渲染成真实dom树
<div id="content"> <p>1</p> <ul class="list-group"></ul> <div>2</div> </div>
- 当我们修改data里面的数据的时候
data.arr.push("<li>listOne</li>") data.arr.push("<li>listTwo</li>") data.arr.push("<li>listThree</li>") - 将之前的虚拟dom树结合新的数据生成一颗新的虚拟dom树
var newDom = { tag:"div",//<div></div> attr:{ id:"content"//<div id="content"></div> }, children:[ {tag:"p",content:1},//<p>1</p> {tag:"ul",attrs:{className:"list-group"},children:[//<ul class="list-group"></ul> {tag:"li",content:"listOne"},//<li>listOne</li> {tag:"li",content:"listTwo"},//<li>listTwo</li> {tag:"li",content:"listThree"}//<li>listThree</li> ]}, {tag:"div",content:2},//<div>2</div> ] }
- 将此次生成好的新的虚拟dom树与上一次的虚拟dom树结构进行对比,对比差异(diff算法)
-
- 将对比出来的差异的部分进行重新真实dom结构的渲染,视图就更新了
<div id="content"> <p>1</p> <ul class="list-group"> <li>listOne</li> <li>listTwo</li> <li>listThree</li> </ul> <div>2</div> </div>






浙公网安备 33010602011771号