处理Fragment
碎片类型的VNode。
// 处理Fragment
const processFragment = (
n1,
n2,
container,
anchor,
parentComponent,
parentSuspense,
isSVG,
optimized
) => {
const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''))
const fragmentEndAnchor = (n2.anchor = n1
? n1.anchor
: hostCreateText(''))
let { patchFlag, dynamicChildren } = n2
if (patchFlag > 0) {
optimized = true
}
if (n1 == null) {
// 初始化挂载
hostInsert(fragmentStartAnchor, container, anchor)
hostInsert(fragmentEndAnchor, container, anchor)
// a fragment can only have array children
// since they are either generated by the compiler, or implicitly created
// from arrays.
// 挂载子节点,这里只能是数组的子集
mountChildren(
n2.children,
container,
fragmentEndAnchor,
parentComponent,
parentSuspense,
isSVG,
optimized
)
} else {
// 更新Fragment
if (
patchFlag > 0 &&
patchFlag & 64 /* STABLE_FRAGMENT */ &&
dynamicChildren &&
// #2715 the previous fragment could've been a BAILed one as a result
// of renderSlot() with no valid children
n1.dynamicChildren
) {
// a stable fragment (template root or <template v-for>) doesn't need to
// patch children order, but it may contain dynamicChildren.
// 稳定片段(template root或<template v-for>)不需要
// 更新整个block,内部会遍历patch
patchBlockChildren(
n1.dynamicChildren,
dynamicChildren,
container,
parentComponent,
parentSuspense,
isSVG
)
if (parentComponent && parentComponent.type.__hmrId) {
traverseStaticChildren(n1, n2)
} else if (
// #2080 if the stable fragment has a key, it's a <template v-for> that may
// get moved around. Make sure all root level vnodes inherit el.
// #2134 or if it's a component root, it may also get moved around
// as the component is being moved.
n2.key != null ||
(parentComponent && n2 === parentComponent.subTree)
)
} else {
// keyed / unkeyed, or manual fragments.
// for keyed & unkeyed, since they are compiler generated from v-for,
// each child is guaranteed to be a block so the fragment will never
// have dynamicChildren.
// 更新子节点,遍历patch
patchChildren(
n1,
n2,
container,
fragmentEndAnchor,
parentComponent,
parentSuspense,
isSVG,
optimized
)
}
}
}
总结:
- 新增:
- 创建 FragmentStart,创建 FragmentEnd
- 挂载所有子节点
mountChildren
- 更新:
- 有动态收集的子节点,
patchBlockChildren
- 更新子节点,
patchChildren
- 有动态收集的子节点,