1.react的虚拟dom
虚拟 DOM 到底是什么,说简单点,就是一个普通的 JavaScript 对象,包含了 tag
、props
、children
三个属性。
<div id="app">
<p class="text">hello world!!!</p>
</div>
上面dom结构转成虚拟dom:
{
tag: 'div',
props: {
id: 'app'
},
chidren: [
{
tag: 'p',
props: {
className: 'text'
},
chidren: [
'hello world!!!'
]
}
]
}
我们调用 setState 时,state 内部状态发生变动,再次调用 render 方法就会生成一个新的虚拟 DOM 树,这样我们就能使用 diff 方法计算出新老虚拟 DOM 发送变化的部分,将变动渲染到视图中。
新旧dom的比较-diff算法
上面代码只是对 VDOM 进行了简单的深度优先遍历,在遍历中,还需要对每个 VDOM 进行一些对比,具体分为以下几种情况:
- 旧节点不存在,插入新节点;新节点不存在,删除旧节点
2. 新旧节点如果都是 VNode,且新旧节点 tag 相同:
2.1 对比新旧节点的属性
2.2对比新旧节点的子节点差异,通过 key 值进行重排序,key 值相同节点继续向下遍历,key值不同的,递归1.
3. 新旧节点如果都是 VText,判断两者文本是否发生变化
4. 其他情况直接用新节点替代旧节点
为什么要使用虚拟dom?
如果不使用虚拟dom:
1. state 数据
2. JSX模版
3. 数据 + 模版结合,生成真实的DOM,来显示
4. state 发生改变
5. 数据 + 模版结合,生成真实的DOM,替换原始的DOM
=>
第一次生成了一个完整的DOM片段
第二次生成了一个完整的DOM片段
第二次的DOM替换第一次的DOM
这三步操作都非常耗性能
使用虚拟dom:
1. state数据
·2. JSX模板
·3. 数据 + 模板相结合,生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真实的DOM),比如
['div', {id: 'abc'}, ['span', {}, 'hello']]
(损耗了极小的性能)
·4.用虚拟DOM的结构生成真实的DOM
<div id = 'abc'><span>hello</span></div>
·5. state 发生变化
·6. 数据 + 模板 生成新的虚拟DOM (极大地提升了性能)
['div', {id: 'abc'}, ['span', {}, 'bye']]
·7. 比较原始虚拟DOM新的虚拟DOM的区别,找到区别是span中的内容(极大地提升了性能)
·8. 直接操作DOM,改变虚拟dom中不同的内容;
优点:
1.性能提升了(dom操作减少)
2.它使得跨端应用得以实现,因为虚拟dom和平台没有关系;