0
点赞
收藏
分享

微信扫一扫

vue的diff算法讲解

佃成成成成 2022-04-17 阅读 56
前端vue.js

文章目录

当数据发生变化时,vue是怎么运作的?

vue会根据真实DOM生成virtual dom,当虚拟DOM节点数据变化时会生成一个新的vnode,然后vnode和oldVnode作对比,如果有不一样的地方就直接修改在真实的dom上,然后将oldVnode更新为vnode,diff的过程就是调用patch(打补丁)函数,比较新旧节点,一边比较一边给真实的DOM打补丁

虚拟DOM和真实DOM都是什么样的?

<div>
	<span>我是真实DOM<</span>
</div>
let vnode = {
	tag: 'div',
	children: [
		{tag: 'span', text: '我是虚拟DOM'}
	]
}

diff过程

在学习diff的过程前,我们需要知道当数据发生变化,会触发obderve中的set方法,set方法会调用Dep.notify通知所有订阅者watcher,订阅者就会调用patch给真实的DOM打补丁(对Vue的observe、watch、compile概念不清楚的可以去看我的vue双向绑定原理文章)

在这里插入图片描述

在patchVnode方法中还调用了一个方法updateChildren

  • 这个方法将vnode的子节点Vch和oldVnode的子节点oldCh作对比进行更新,简单来说就是,将就节点集合以新节点集合为标准调整

  • oldCh和vCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明oldCh和vCh至少有一个已经遍历完了,就会结束比较

大家来跟我看图就明白了
在这里插入图片描述
oldVnode是更新前的节点,vnode是更新后的节点,那么我们来看看,旧节点集合是怎么根据新节点集合来进行调整的

第一步:
在这里插入图片描述

现在分别对oldS、oldE、S、E两两做sameVnode比较,有四种比较方式,当其中两个能匹配上那么真实dom中的相应节点会移到Vnode相应的位置

  • 如果是oldS和E匹配上了,那么真实dom中的第一个节点会移到最后
  • 如果是oldE和S匹配上了,那么真实dom中的最后一个节点会移到最前,匹配上的两个指针向中间移动
  • 如果四种匹配没有一对是成功的,那么遍历oldChild,S挨个和他们匹配,匹配成功就在真实dom中- 将成功的节点移到最前面,如果依旧没有成功的,那么将S对应的节点插入到dom中对应的oldS位置,oldS和S指针向中间移动。

第二步:
a = oldS, c = oldE
a = s, b = e
oldS和s匹配上了,但是都在第一个,所以不用做任何操作
此时DOM为a b d
,最后oldS指针和s指针向内部移动oldS指向旧集合的b,s指向新集合的c

第三步:
在这里插入图片描述
b = oldS, d = oldE
c = s, b = e
发现oldS指针和e指针指向的内容匹配,所以将旧集合中的b元素移动到最后 (当其中两个能匹配上那么真实dom中的相应节点会移到Vnode相应的位置)
此时DOM为a d b
,最后oldS指针和e指针向内部移动oldS指向旧集合的d,e指向新集合的d

第四步:
在这里插入图片描述
d = oldE, d = oldS
c = s, d = e
发现oldE和d是匹配的,位置不变
然后oldS++ ,oldE-- oldS > oldE,遍历结束,说明oldCh先遍历完,将剩余的节点按照自己的index插入到真是dom中,此时DOM为a d d b

举报

相关推荐

vue中的diff算法

Vue的虚拟DOM及diff算法

Vue的diff算法原理是什么?

Vue 虚拟DOM和diff算法

0 条评论