预处理优化
const patchChildren: PatchChildrenFn = () => {
// 获得当前新旧节点下的子节点们
const c1 = n1 && n1.children
const prevShapeFlag = n1 ? n1.shapeFlag : 0
const c2 = n2.children
const { patchFlag, shapeFlag } = n2
// fragment有两种类型的静态标记:子节点有key、子节点无key
if (patchFlag > 0) {
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
// 子节点全部或者部分有key
patchKeyedChildren()
return
} else if (patchFlag & PatchFlags.UNKEYED_FRAGMENT) {
// 子节点没有key
patchUnkeyedChildren()
return
}
}
// 子节点有三种可能:文本节点、数组(至少一个子节点)、没有子节点
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
// 匹配到当前是文本节点:卸载之前的节点,为其设置文本节点
unmountChildren()
hostSetElementText()
} else {
// old子节点是数组
if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) {
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
// 现在(new)也是数组(至少一个子节点),直接full diff(调用patchKeyedChildren())
} else {
// 否则当前没有子节点,直接卸载当前所有的子节点
unmountChildren()
}
} else {
// old的子节点是文本或者没有
if (prevShapeFlag & ShapeFlags.TEXT_CHILDREN) {
// 清空文本
hostSetElementText(container, '')
}
// 现在(new)的节点是多个子节点,直接新增
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
// 新建子节点
mountChildren()
}
}
}
}最后更新于