最近比较流行的前端框架都涉及到了虚拟dom的概念。那什么是虚拟dom呢?
目前我们都是数据驱动视图。页面的更新根据数据的变化而变化。之前研究vue的双向绑定时候,就是我们的数据变化后通过set函数对页面的dom进行更新以达到视图的刷新。
不过在前端中,操作dom的代价是很高的而且还很慢。一不小心可能会导致页面重排。这样性能就十分低了。相对于 DOM 对象,原生的 JavaScript 对象处理起来更快。dom的树结构,我们可以通过对象的树结构描述出来。例如
<ul id='list'>
<li class='item'>Item 1</li>
<li class='item'>Item 2</li>
<li class='item'>Item 3</li>
</ul>
写成js对象可以为
var tree = {
tagName: 'ul',
props: { id: 'list' },
child: [
{tagName : 'li' , props: {class: 'item'}, ["Item 1"]},
{tagName : 'li' , props: {class: 'item'} ,["Item 2"]},
{tagName : 'li' , props: {class: 'item'}, ["Item 3"]},
]
}
既然我们可以把dom树用js对象表示出来。当数据变化需要更新dom的时候,我们首先更新我们的js对象。然后对比更新对象的差异,算出对dom最少的更新,根据差异去更新真实的dom。这样就可以最少的保证部分更新dom来展示结果了。
假设我们现在的html里不写dom元素
vue中的虚拟dom
我们写vue的时候。会在template模板写一些html标签。这些并不是直接就能识别为dom的。我们解析template的时候,会生成一个相对于的render函数。Vue的编译器在编译模板之后,会把这些模板编译成一个渲染函数。而函数被调用的时候就会渲染并且返回一个虚拟DOM的树。
然后每个组件都会有相应的render函数。数据更新时候出发setter,继而出发render函数生成新的虚拟dom对象继而使用diff算法去更新真正的dom。之前分析双向绑定机制的时候,解析dom是compile.js。之前的功能是分析dom的指令,获取指令的值,然后调用compile.update跟新dom,现在这个js的功能首先是生成相对应的render函数。然后render生成对象。通过对象的分析(而不是之前的直接dom分析)获取指令的值。然后再跟新dom。
模板渲染
网友评论