虚拟 DOM 与 DOM diff
虚拟 DOM
一个能代表 DOM 树的对象,通常含有标签名、标签上的属性、事件监听和子元素们,以及其他属性。
一种说法:DOM 操作慢,虚拟 DOM 快 DOM 操作慢是对比于 JS 原生 API ,如数组操作。 任何基于 DOM 的库( Vue/React )都不可能在操作 DOM 时比 DOM 快。
为什么网上会有这种谣言?
在某些情况下,确实虚拟 DOM 快。
1、虚拟 DOM 优点
(1)减少 DOM操作 (减少次数和范围)
虚拟 DOM 可以将多次操作合并为一次操作。比如添加1000个节点,DOM 是一个接一个操作的,需要操作1000次,而虚拟 DOM 只需要操作1次。
虚拟 DOM 借助 DOM diff 可以把多余的操作省掉。比如添加1000个节点,其实只有10个是新增的。DOM 是全部更新,而虚拟 DOM 只需要更新新增的。
(2)跨平台
虚拟 DOM 不仅可以变成 DOM ,还可以变成小程序、iOS应用、安卓应用,因为虚拟 DOM 本质上是一个 JS 对象。
React中的虚拟 DOM
const vNode = {
key:null,
props:{
children:[ //子元素们
{type:'span',...},
{type:'span',...}
],
className:"red" //标签上的属性
onClick:()=>{} //事件
},
ref:null,
type:"div", //标签名 or 组件名
...
}
Vue中的虚拟 DOM
const vNode = {
tag:"div", //标签名 or 组件名
data:{
class:"red", //标签上的属性
on:{
click:()=>{} //事件
}
},
children:[ //子元素们
{type:'span',...},
{type:'span',...}
],
...
}
创建虚拟 DOM
React 中使用 createElement
简化:通过 babel 转为 createElement 形式
<div className="red" onClick={fn}>
<span>span1</span>
<span>span2</span>
</div>
Vue 中使用 h(只能在 render 函数里得到 h )
简化:通过 vue-loader 转为 h 形式
<div class="red" @click="fn">
<span>span1</span>
<span>span2</span>
</div>
2、虚拟 DOM 缺点
需要额外的创建函数,如 createElement 或 h,但可以通过 JSX 来简化成 XML 写法。(补救后的缺点:严重依赖打包工具,要添加额外的构建过程)
DOM diff
一个函数,称之为patch changed = patch(oldVNode,newVNode) changed就是要运行的 DOM 操作
[
{type:'INSERT',vNode:...},
{type:'TEXT',vNode:...},
{type:'PROPS',propsPatch:[...]}
]
个人理解与学习建议
1. 实践是关键
学习编程语言最好的方法就是不断地实践。通过编写小项目、练习题,可以更好地理解所学知识,并在实际应用中发现问题并解决它们。
2. 阅读优秀代码
阅读他人的优秀代码是学习的好途径。通过阅读开源项目或其他人的代码,可以学到不同的编码风格、解决问题的方法等。
3. 持续学习更新
前端技术日新月异,保持持续学习的心态是非常重要的。关注新的语言特性、框架、工具,保持与行业的同步。
4. 解决实际问题
学习不仅仅是为了掌握知识,更是为了解决实际问题。在学习过程中,尝试解决一些实际项目中遇到的问题。