认识
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
没有必要打补丁, 将旧节点清空直接挂载新节点就好了。