#博学谷IT学习技术支持#
目录
1、什么是Virtual DOM
Virtual Dom(虚拟DOM)
,是由普通的JS
对象来描述DOM
对象,因为不是真实的DOM
对象,所以叫做Virtual DOM
.
我们为什么用虚拟DOM
来模拟真实的DOM
呢?
因为我们知道一个DOM
对象中的成员是非常多。所以创建Dom
对象的成本非常高。
如果使用虚拟Dom
来描述真实Dom
,就会发现创建的成员少,成本也就低了。
2、为什么使用Virtual DOM
-
手动操作
Dom
比较麻烦,还需要考虑浏览器兼容性问题,虽然有Jquery
等库简化DOM
操作,但是随着项目的复杂度越来越高,DOM
操作复杂提升,既要考虑Dom
操作,还要考虑数据的操作。 -
为了简化
DOM
的复杂操作于是出现了各种的MVVM
框架,MVVM
框架解决了视图和状态的同步问题,也就是当数据发生变化,更新视图,当视图发生变化更新数据。 -
为了简化视图的操作我们可以使用模板引擎,但是模板引擎没有解决跟踪状态变化的问题(当数据发生了变化后,无法获取上一次的状态,只有将页面上的元素删除,然后在重新创建,这时页面有刷新的问题,同时频繁操作
Dom
,性能也会非常低),于是Virtual Dom
出现了。 -
Virtual Dom
的好处就是当状态改变时不需要立即更新DOM
,只需要创建一个虚拟树来描述DOM
,Virtual Dom
内部将弄清楚如何有效(diff
)的更新DOM
.(例如:向用户添加列表中添加一个用户,只添加新的内容,原有的结构会被重用)下面,我们看一段代码,该代码是使用
jquery
来实现的数据展示与排序,是纯DOM
操作的方式
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
</head>
<body>
<div id="app">
</div>
<div id="sort" style="margin-top: 20px;">按年纪排序</div>
<script type="text/javascript">
var datas = [
{ 'name': 'kongzhi11', 'age': 32 },
{ 'name': 'kongzhi44', 'age': 29 },
{ 'name': 'kongzhi22', 'age': 31 },
{ 'name': 'kongzhi33', 'age': 30 }
];
var render = function() {
var html = '';
datas.forEach(function(item, index) {
html += `<li>
<div class="u-cls">
<span class="name">姓名:${item.name}</span>
<span class="age" style="margin-left:20px;">年龄:${item.age}</span>
<span class="closed">x</span>
</div>
</li>`;
});
return html;
};
$("#app").html(render());
$('#sort').on('click', function() {
datas = datas.sort(function(a, b) {
return a.age - b.age;
});
$('#app').html(render());
})
</script>
</body>
</html>
如上demo
排序,虽然在使用jquery
时代这种方式是可行的,我们点击按钮,它就可以从小到大的排序,但是它比较暴力,它会将之前的dom
全部删除,然后重新渲染新的dom
节点,我们知道,操作DOM
会影响页面的性能,并且有时候数据根本就没有发生改变,我们希望未更改的数据不需要重新渲染操作。
因此虚拟DOM
的思想就出来了,虚拟DOM
的思想是先控制数据再到视图,但是数据状态是通过diff
比对,它会比对新旧虚拟DOM
节点,然后找出两者之前的不同,然后再把不同的节点再发生渲染操作。
总结:
虚拟DOM
可以维护程序的状态,跟踪上一次的状态
通过比较前后两次状态的差异来更新真实DOM
3、虚拟DOM的作用
维护视图和状态的关系(虚拟DOM
会记录状态的变化,只需要更新状态变化的内容就可以了)
复杂视图情况下提升渲染性能。
下面我们看一个案例,该案例的功能比较简单,单击按钮后,更新div
中的内容。
let div=document.querySelector('#app')
let btn=document.querySelectory('#btn')
btn.onclick=function(){
div.textContent='Hello World'
}
以上代码非常简单,而且是使用DOM
操作的方式来实现的。
如果上面的案例,我们使用虚拟DOM
来实现,应该怎样处理呢?首先,我们要创建一个虚拟DOM
的对象,
虚拟DOM
对象就是一个普通的JS
对象。当单击按钮的时候,需要对比两次状态的差异。所以说,仅仅是该案例,
我们使用虚拟DOM
的方式来实现,要比使用纯DOM
的方式来实现,性能要低。
所以说,并不是所有的情况下使用虚拟DOM
都会提升性能的。只有在视图比较复杂的情况下使用虚拟DOM
才会提升渲染的性能。
虚拟DOM
除了渲染DOM
以外,还可以实现渲染到其它的平台,例如可以实现服务端渲染(ssr
),原生应用(React Native
),小程序(uni-app
等)。以上列举的案例中,内部都使用了虚拟DOM
.
Vue
中虚拟DOM
生成真实DOM
的过程