关于虚拟DOM的一点总结
Posted 小二007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于虚拟DOM的一点总结相关的知识,希望对你有一定的参考价值。
一、为什么vue、react会这么火?
记得刚入前端的时候jquery还是比较火的,各种各样的jquery插件层出不穷,结果没想到2年时间不到,jquery已经快要寿终正寝了。与之相对的是vue、react、angualr这些框架你方唱罢我登场,社区也是异常活跃。总的来说这些框架都做了同一件事情,就是模块化、组件化。以前我们开发的思想是把html、css、js单独分离开来,但是受限于html是没有作用域的,导致写页面的时候很难写一些公共的组件(比如头部导航条)。而现在也是得益于requirejs、seajs这些模块加载器(推荐使用ES6的模块加载)以及webpack、gulp这种构建工具的出现,现在的思想转变为把html写到js里面,这样html就有了作用域就能单独写一个独立的组件了。
二、什么是虚拟dom
vue、react不仅能写单独写组件,而且性能还比较高,主要是得益于虚拟dom,我们知道页面渲染成本最高的就是dom操作了,假设我们要改变某个元素的颜色和高度。最low的是下面这种方式。
$("xx").css("height",xx);
$("xx").css("color",xx)
这种方式做的话会渲染2次,成本比较高,所以我们常用的方法是给它增加一个class,然后添加或者移除这个class就可以了。angular1属于mvvm的模式,每一个视图都会对应一个状态,只要是状体变化了,页面不用手动操作Dom,而是替换一个视图层,然后用innerHtml一下就可以啦,这样做就比较消耗性能,而react和vue是将整个Dom树生成一个对应的js对象(虚拟Dom),虚拟Dom其实就是一个缓存,每次改变的时候,都会对这个缓存进行比较,看哪里变化了然后重新渲染那里,并且更新这个缓存,举个栗子
<ul id='list'>
<li class='item'>Item 1</li>
<li class='item'>Item 2</li>
<li class='item'>Item 3</li>
</ul>
对于这段html代码,vue和react都先会将这个Dom对象转换为js对象,只不过形式不一样。vue常见用.vue这个单文件形式,react用jsx形式,最后通过render函数将这个js对象渲染成真正的Dom节点。
let element = {
tagName: 'ul',
props: {
id: 'list'
},
children: {
{
tagName: 'li',
props: {class: 'item'},
children: ["Item 1"]
},
{
tagName: 'li',
props: {class: 'item'},
children: ["Item 2"]
},
{
tagName: 'li',
props: {class: 'item'},
children: ["Item 3"]
}
}
}
这个对象把Dom树上的信息都用js对象反应出来啦,我们就可以通过这个对象构建出一个真正的Dom树。vue和react都有自己一套成熟的算法(diff算法)会根据每次改变算出这个虚拟的Dom对象哪里发生变化啦,然后再把相应发生变化的地方重新渲染一次(而不是整个变化)。需要注意这里Dom渲染是异步的,这样能尽量减少重复渲染,你改变数据的时候不能实时渲染出来,vue可以通过$nextTick来实时获取真实的Dom。
三、如何快速学习vue和react
1.开发思想要变化,我们要用数据去管理整个项目,而不是手动去改变Dom。
2.刚开始学习这些新框架的时候真是痛不欲生,特别是react,有非常多的ES6的知识点,所以如果要学好这些新框架,首先一定要好好学习一下ES6,ES6和ES5相比改变还是有些大的,常用的有块级作用域、类、箭头函数、字符串模版、rest、解构、模块等,如果不懂这些,学习react就会有很多看不懂的地方。
3.理解组件,和Dom树一样,如果用这些框架也会有一颗组件树,整个页面也是由一个个组件构成,组件之间的通信如果父到子可以通过props继承下去,子到父可以通过$emit事件订阅方式,如果是非直接相关的2个组件,简单的vue可以通过bus,如果项目业务逻辑复杂的,react可以通过redux,vue可以通过vuex进行管理。
以上是关于关于虚拟DOM的一点总结的主要内容,如果未能解决你的问题,请参考以下文章