手机版

vue2.0虚拟DOM渲染思想分析

时间:2021-08-30 来源:互联网 编辑:宝哥软件园 浏览:

1.为什么需要虚拟DOM

之前我们从头开始写了一个简单的类似Vue的框架(文章链接),其中模板解析和渲染由Compile函数完成,使用文档片段,而不是直接操作页面中的DOM元素。数据更改后,真正的DOM被appendChild函数插入到页面中。

虽然使用了文档片段,但是操作的是真实的DOM。

而且我们知道操作DOM的成本很高,所以vue2.0用虚拟DOM代替真实DOM,最后通过某种机制更新真实DOM并渲染视图。

所谓虚拟DOM,其实就是用JS来模拟DOM结构,把DOM更改操作放在JS层,尽量减少DOM操作(个人认为主要是因为JS操作比DOM操作快很多倍,而且JS操作效率高)。然后对比前后虚拟DOM的变化,只有变化的部分会重新渲染,没有变化的部分不会重新渲染。

例如,我们有下面的DOM结构。

ul id=' list ' Li class=' item 1 ' item 1/Li Li class=' item 2 ' item 2/Li/ul我们可以用JS对象来模拟上面的DOM结构,模拟后会变成下面的结构。

var vdom={ tag: 'ul ',attr: { id: 'list ',},children 3360[{ tag: 'li ',attrs: { className: 'item ',children: ['Item 1'] },},{ tag : ' Li ',attrs: { className: 'item ',Children: ['item2']}}

2.如何使用虚拟DOM

Vue在2.0版本中引入了vdom。vdom是基于snabbdom库修改的。Snabbdom是一个开源的vdom库。

snabbdom的主要功能是将传入JS模拟的dom结构转换为虚拟DOM节点。

首先通过H函数将JS模拟的DOM结构转换为虚拟DOM,然后通过patch函数将虚拟DOM转换为真实DOM,再渲染到页面上。

为了保证页面的最小渲染,snabbdom引入Diff算法,找出前后两个虚拟dom的区别,只更新变化的DOM节点,不作为变化的DOM节点重新渲染。

我这里不打算分析snabbdom的源代码来解释snabbdom到底是怎么做到的(主要原因是现阶段还没有达到那个水平,哈哈。而且很多同学都做过类似的分析,相关链接附在文末。

我将从snabbdom的使用角度来看Vue中的虚拟DOM是如何完成视图渲染的。

让我们首先看看snabbdom中两个核心API的功能。

h()函数:将JS模拟的传入DOM结构模板转换为vnode。(vnode是纯JS对象)patch()函数:将虚拟DOM节点渲染到页面。

我们提供一个例子来看看snabbdom的实际功能。

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' meta name=' viewport ' content=' width=device-width,initial-scale=1.0 ' meta http-equiv=' X-UA-Compatible ' content=' ie=edge ' title document/title/head dy div id=' container '/div button id=' BTN-change ' change/button!-介绍snabbdom库,不用担心为什么介绍,也不用担心每个文件的功能。本文只介绍了虚拟DOM的工作模式,不涉及原理分析,主要是因为目前博主还比较薄弱。感兴趣的伙伴可以单独研究-script src=' http :3359 cdn . bootscs.com/snabbdom/0 . 7 . 1/snabbdom . js '/script src=' http 3360https://cdn.bootcss.com/snabbdom/0 . 7 . 1/snabbdom-class . js '/script script src=' http :3359 cdn . bootscs.com/snabbdom/0 . 7 . 1/snabbdom-props . js '/script script src='//生成vnode var vnode=h ('ul # list ',{},[h ('li.item ',{},['item1']),h ('li.item ',{},['item2']),]//console . log .//获取容器var container=document . getelementbyid(' container ');补丁(容器、vnode);//第一次呈现varbtn=document . getelementbyid(' BTN-change ');BTN . onclick=function(){ var new vnode=h(' ul # list ',{},[ h('li.item ',{},['Item 1']),h('li.item ',{},['Item B']),h('li.item ',{},['Item 3']),]) patch(vnode,new vnode);//再次渲染vnode=newVnode//将修改后的newVnode赋给vnode }/脚本/正文/html思想分析:

我们首先通过H函数创建一个虚拟DOM节点,通过补丁函数将虚拟DOM渲染到页面上。点击btn按钮更新ul #列表的数据,更改第二个li元素的值并添加一个新的li元素,但第一个li元素的值保持不变。我们再次使用patch函数将更新的数据呈现到页面上。可以看到,只有第二个和第三个li已经更新,而第一个li没有被重新渲染,因为它没有改变。

vue中模板解析和渲染的核心是通过snabbdom的H()和patch()等函数将模板解析成vnode。如果是主渲染,vnode会通过patch(容器,vnode)渲染到页面;如果是二次渲染,将使用patch(vnode,newVnode)通过Diff算法比较原始vnode和newVnode之间的差异

摘要

以上是边肖介绍的vue2.0的虚拟DOM渲染思路分析,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

版权声明:vue2.0虚拟DOM渲染思想分析是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。