From: daiwei Date: Fri, 25 Jul 2025 13:51:07 +0000 (+0800) Subject: fix(runtime-vapor): improve fallback handling for nested fragments X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5c6e533273c1728b115572633143ed02a2659838;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-vapor): improve fallback handling for nested fragments --- diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index 7c178e894b..c2b08a9806 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -74,18 +74,19 @@ export class DynamicFragment extends VaporFragment { if (this.fallback) { // set fallback for nested fragments - const isFrag = isFragment(this.nodes) - if (isFrag) { + const hasNestedFragment = isFragment(this.nodes) + if (hasNestedFragment) { setFragmentFallback(this.nodes as VaporFragment, this.fallback) } - if (!isValidBlock(this.nodes)) { + const invalidFragment = findInvalidFragment(this) + if (invalidFragment) { parent && remove(this.nodes, parent) const scope = this.scope || (this.scope = new EffectScope()) scope.run(() => { - if (isFrag) { - // render fragment's fallback - renderFragmentFallback(this.nodes as VaporFragment) + // for nested fragments, render invalid fragment's fallback + if (hasNestedFragment) { + renderFragmentFallback(invalidFragment) } else { this.nodes = this.fallback!() || [] } @@ -102,9 +103,10 @@ function setFragmentFallback( fragment: VaporFragment, fallback: BlockFn | undefined, ): void { - if (!fragment.fallback) { - fragment.fallback = fallback - } + // stop recursion if fragment has its own fallback + if (fragment.fallback) return + + fragment.fallback = fallback if (isFragment(fragment.nodes)) { setFragmentFallback(fragment.nodes, fallback) } @@ -114,17 +116,20 @@ function renderFragmentFallback(fragment: VaporFragment): void { if (fragment instanceof ForFragment) { fragment.nodes[0] = [fragment.fallback!() || []] as Block[] } else if (fragment instanceof DynamicFragment) { - const nodes = fragment.nodes - if (isFragment(nodes)) { - renderFragmentFallback(nodes) - } else { - fragment.update(fragment.fallback) - } + fragment.update(fragment.fallback) } else { // vdom slots } } +function findInvalidFragment(fragment: VaporFragment): VaporFragment | null { + if (isValidBlock(fragment.nodes)) return null + + return isFragment(fragment.nodes) + ? findInvalidFragment(fragment.nodes) || fragment + : fragment +} + export function isFragment(val: NonNullable): val is VaporFragment { return val instanceof VaporFragment }