跳到主要内容

认识

2023年07月17日
柏拉文
越努力,越幸运

一、认识


首次渲染时已经将 oldVNode 渲染到 container 内, 当再次调用 render 函数尝试渲染 newVNode 时,渲染器 会使用 newVNode 与上一次渲染的 oldVNode 进行比较, 视图找到并更新变更点, 这个过程叫做 打补丁(更新)(patch)

patch 是整个渲染器的核心入口,承载了最重要的渲染逻辑。基本实现如下所示:

const patch = (n1,n2,container,anchor)=>{
if(n1 === n2){
return;
}
if(n1 && n1.type !== n2.type){
/**
* @description: 如果新旧 vnode 类型不同, 直接将旧 vnode 卸载
* 描述: 对于 type 不同的元素来说, 每个元素都有特有的属性, 不存在打补丁的意义。在 type 不同的情况下, 先将旧 vnode 卸载, 再将新 vnode 挂载到容器中, 将旧 vnode 置为空, 这样才能保证后续挂载操作正确执行。
*/
unmount(n1);
n1 = null;
}

const{ type } = n2;
switch(type){
case Text:
processText(n1,n2,container,anchor);
break;
case Comment:
processCommentNode(n1,n2,container,anchor);
break;
case Static:
break;
case Fragment:
break;
default:
if(shapeFlag & ShapeFlags.ELEMENY){
processElement(n1,n2,container,anchor);
}else if(shapeFlag & ShapeFlags.COMPONENT){

}else if(shapeFlag & ShapeFlags.TELEPORT){

}else if(shapeFlag & ShapeFlags.SUSPENSE){

}
}
}

二、细节


2.1 n1 === n2

n1 === n2 , 新旧 vnode 相同, patch 不做任何处理。

2.2 n1.type === n2.type

n1.type === n2.type 新旧 vnode.type 相同的情况下, 才有 patch 打补丁的必要。如果 n1.type !== n2.type 没有必要打补丁, 将旧节点清空直接挂载新节点就好了。

2.3 区分 n2.type