DOM 和 虚拟DOM
DOM:浏览器中,提供的概念;用JS对象,表示页面上的元素,并提供了操作元素的AP
虚拟DOM:是框架中的概念;手动用JS对象来模拟DOM元素和嵌套关系
实现虚拟DOM的目的
为了实现页面中,DOM元素的高效更新
虚拟DOM
- state数据
- JSX模板
- state数据+JSX模板相结合,生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真实的DOM)
['div', {id: 'abc'}, ['span', {}, 'hello']](损耗了极小的性能)
- 用虚拟DOM的结构生成真实的DOM
<div id = 'abc'><span>hello</span></div>
- state发生变化
- 数据+模板生成新的虚拟DOM(极大地提升了性能)
['div', {id: 'abc'}, ['span', {}, 'bye']]
- 比较原始虚拟DOM和新的虚拟DOM的区别,找出区别是span中的内容
- 直接操作DOM,改变span中的内容
虚拟DOM中的diff 算法
同层比对,列表使用不同的key值
用虚拟DOM完成数据驱动涉及到关键的一点就是如何比较两个虚拟DOM的差异
diff算法中只会比较同级的元素,一旦发现某一级有所不同,则会把其子级丢弃,直接用新的差异的以及以及其下的所有自己替换。这也做的好处就是算法简单,也就提高了比对速度,因此也提升了性能
for循环中如果没有给每个item所在标签增加一个key值,vue和react中都会发出警告,建议我们加上,这是因为当进行虚拟DOM比对时,我们需要比较出相同的元素和不同的,没有key我们就很难一一对应,需要做两层循环比较,用上了key值则我们可以清楚比较出哪一个新增或删除了什么
有了key值我们就容易判别z 是新加的元素找到差异
注意:开发中尽量不要用index作为key的值
在循环中key值最好不要用index的原因?
如果key值使用index的话,就可能无法使原始的虚拟DOM中的key值和新的虚拟DOM中的key值一致,从而不能充分发挥diff算法的优势。
比如一个数组里有数据a b c,用index表示的key分别为0 1 2
当删除a时,b c的key分别为0 2,从而导致元素的新旧key值不一样,即key值不稳定,所以key值就失去其存在的意义了
参考此文档