vnode是vue中的虚拟dom节点对象
什么是虚拟dom节点:不是真实的dom节点,是js对象。
template:
<div id="app">
<p>{{message}}</p>
<button @click="btnAction">按钮</button>
</div>
1.第一渲染,需要根据template中的模版,渲染出来初始的dom结构
<div id="app">
<p>hello world</p>
<button>按钮</button>
</div>
2.this.message = ‘hi’
第二次重新渲染,渲染完之后替换原来的dom
<div id="app">
<p>hi</p>
<button>按钮</button>
</div>
数据发生变化后,页面需要实现响应,主要性能消耗在以下两个地方:
重新根据template构建新的真实的dom 替换第一次已经渲染在html页面上的dom
第一次优化为:
重新根据template构建新的真实的dom 不直接替换,重新构建的真实dom跟第一次构建的真实dom进行比对
发现如果有不一样的地方,只替换不一样的地方。
(解决了整体替换dom带来的性能消耗,但是增加了比对dom树带来的性能消耗)
第二次优化为:
引入虚拟dom的概念
1.第一次渲染:根据template的模版,构建一个虚拟dom,这个虚拟dom指的是js对象
['div', {id: 'app'}, [['p', {}, 'hello world'], ['button', {}, '按钮']]]
{
elementName: 'div',
attrs: {
id: 'app'
},
children: [
{
elementName: 'p',
attrs: {},
children: ['hello world']
},
{
elementName: 'button',
attrs: {},
children: ['按钮']
}
]
}
这个虚拟dom对象描述了真实的dom的内容
这个虚拟dom,通过compiler方法,把虚拟dom转为真实的dom。
虚拟dom缓存起来,真实dom挂载到html上。
第一次的渲染就完成了。
2.当数据发生变化时:
根据template的模版,重新构建一个虚拟dom。
['div', {id: 'app'}, [['p', {}, 'hi'], ['button', {}, '按钮']]]
比对第一次缓存下来的虚拟dom,跟第二次重新构建的虚拟dom,有何不同。(diff算法对比)
找到不同。
根据不同的虚拟dom,构建真实dom
然后,使用真实dom替换html中dom不同的位置。
第二次优化的好处:
重新根据template构建新的真实的dom 不直接替换,重新构建的虚拟dom跟第一次构建的虚拟dom进行比对
第一次渲染不可避免,都得全部渲染为真实dom 发现如果有不一样的地方,只替换不一样的地方
但是第二次渲染可以只构建有变化的dom