VUE源码解析:5、初识diff算法

diff算法总结

1、为什么节点要加上key:key是这个节点的唯一标识,告诉diff算法,更改前后,他们是同一个dom节点。
2、只有同一个虚拟节点,才会进行diff算法(选择器相同,key相同),否则就会暴力删除旧的,插入新的
3、diff算法只进行同层比较,不会跨层比较,即使是用了同一片虚拟节点,但是跨层了,对不起,精细化不diff你,而是暴力删除旧的,插入新的
下面新建index.js来测试上面的三种情况,

1、为什么节点要加上key

// index.html中新增一个button按钮,一会来测试更改dom后,diff算法如何精细化比较
// <button id="btn">点击改变dom</button>
import {
	init,
	classModule,
	propsModule,
	styleModule,
	eventListenersModule,
	h,
} from "snabbdom";
//创建出patch函数(diff算法的核心函数),patch函数可以服务与让虚拟节点上树
const patch = init([init, classModule, propsModule, styleModule, eventListenersModule])
const container = document.getElementById('container')
const btn = document.getElementById('btn')

// 示例一:
const vnode1 = h('ul',{},[
	h('li',{ key:'A' },'A'),
	h('li',{ key:'B' },'B'),
	h('li',{ key:'C' },'C'),
	h('li',{ key:'D' },'D'),
])
const vnode2 = h('ul',{},[
	h('li',{ key:'A' },'A'),
	h('li',{ key:'B' },'B'),
	h('li',{ key:'C' },'C'),
	h('li',{ key:'D' },'D'),
	h('li',{ key:'E' },'btn点击后:新增的E'),
])
// 渲染节点,请看下图1,
patch(container, vnode1) 
// 点击按钮 将 vnode1 变为 vnode2,
// 为了更好理解diff算法,这里我们手动将节点A文字更改一下,
// 当按钮触发后,会发现,只是新增了E,而之前的节点没有改变,说名,diff算法只是做了精细化比较。
// 请看下图2
btn.onclick = function(){
	patch(vnode1, vnode2)
}

在这里插入图片描述
在这里插入图片描述

2、只有同一个虚拟节点,才会进行diff算法(选择器相同,key相同),否则就会暴力删除旧的,插入新的

// 示例二:
// 注意:我们把父节点ul换成了ol,这个时候选择器不相同,diff就会暴力删除vnode3 ,插入vnode4
// 为了更好的理解,在html中我们直接把文字修改了,看下是不是会直接删除vnode3 ,查看图3,图4
// 查看图4可知,因为父节点不同,diff算法直接删除了旧的,插入新的。
const vnode3 = h('ul',{},[
	h('li',{ key:'A' },'A'),
	h('li',{ key:'B' },'B'),
	h('li',{ key:'C' },'C'),
	h('li',{ key:'D' },'D'),
])
const vnode4 = h('ol',{},[
	h('li',{ key:'A' },'A'),
	h('li',{ key:'B' },'B'),
	h('li',{ key:'C' },'C'),
	h('li',{ key:'D' },'D'),
])
patch(container, vnode3)
btn.onclick = function(){
	patch(vnode3, vnode4)
}

在这里插入图片描述
在这里插入图片描述

3、diff算法只进行同层比较,不会跨层比较,即使是用了同一片虚拟节点,但是跨层了,对不起,精细化不diff你,而是暴力删除旧的,插入新的

// 示例三:
// vnode6多了一层section标签,这里不会进行diff。直接删除旧的,插入新的
// 查看图5,图6
const vnode5 = h('div',{},[
	h('p',{ key:'A' },'A'),
	h('p',{ key:'B' },'B'),
	h('p',{ key:'C' },'C'),
	h('p',{ key:'D' },'D'),
])
const vnode6 = h('div',{},h('section',{},[
	h('p',{ key:'A' },'A'),
	h('p',{ key:'B' },'B'),
	h('p',{ key:'C' },'C'),
	h('p',{ key:'D' },'D'),
]))
patch(container, vnode5)
btn.onclick = function(){
	patch(vnode5, vnode6)
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值