diff算法-h函数-虚拟dom
虚拟dom
就是一个用来描述真实Dom的对象
它有六个属性,sel
表示当前节点标签名,sel
表示当前节点标签名,data
内是节点的属性,children
表示当前节点的其他子标签节点,elm
表示当前虚拟节点对应的真实节点(这里暂时没有),key
即为当前节点的key,text
表示当前节点下的文本,结构类似这样。
let vnode = {
sel: 'ul',
data: {},
children: [
{
sel: 'li', data: { class: 'item' }, text: 'son1'
},
{
sel: 'li', data: { class: 'item' }, text: 'son2'
},
],
elm: undefined,
key: undefined,
text: undefined
}
h函数
1、h函数,就是render函数里面传入的那个h函数
2、函数可以接受多种类型的参数,但其实它内部只干了一件事,就是执行vnode函数
。根据传入h函数的参数来决定执行vnode函数
时传入的参数。那么vnode函数
又是干什么的呢?vnode函数
其实也只干了一件事,就是把传入h函数的参数转化为一个对象,即虚拟Dom。
// vnode.js
export default function (sel, data, children, text, elm) {
const key = data.key
return {sel, data, children, text, elm, key}
}
diff算法
patch
1、比较的第一步就是执行patch,它相当于对比的入口。既然是对比两个虚拟Dom,那么就将两个虚拟Dom作为参数传入patch中。patch的主要作用是对比两个虚拟Dom的根节点,并根据对比结果操作真实Dom。
patchVnode
1、patchVnode用来比较两个虚拟节点的子节点并更新其子节点对应的真实Dom节点
updateChildren
1、该方法是diff算法中最复杂的方法(大的要来了)。对应上面patchVnode中oldVnode
和newVnode
都有children的情况。
diff 算法是一种通过同层的树节点进行比较的高效算法
其有两个特点:
1、比较只会在同层级进行, 不会跨层级比较
2、在diff比较的过程中,循环从两边向中间比较,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较,尽量复用节点,最后更新真实的dom
key值
1、如果两个不同节点的标签名恰好相同,那么就会被判定为同一个节点(key都为undefined),结果一对比这两个节点的子节点发现不一样,这样会凭空增加很多对真实Dom的操作,从而导致页面更频繁得进行重绘和回流。