]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: tweaks
authordaiwei <daiwei521@126.com>
Tue, 22 Jul 2025 02:31:16 +0000 (10:31 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 22 Jul 2025 05:56:19 +0000 (13:56 +0800)
packages/runtime-vapor/__tests__/componentSlots.spec.ts
packages/runtime-vapor/src/block.ts

index f54137724ccbc60b099823bba234e7c51e14f89b..608a0ff556855ac482985ad6fed882f1c014de76 100644 (file)
@@ -561,5 +561,64 @@ describe('component: slots', () => {
       await nextTick()
       expect(html()).toBe('fallback<!--if--><!--slot-->')
     })
+
+    test('render fallback with nested v-if ', async () => {
+      const Child = {
+        setup() {
+          return createSlot('default', null, () =>
+            document.createTextNode('fallback'),
+          )
+        },
+      }
+
+      const outerShow = ref(false)
+      const innerShow = ref(false)
+
+      const { html } = define({
+        setup() {
+          return createComponent(Child, null, {
+            default: () => {
+              return createIf(
+                () => outerShow.value,
+                () => {
+                  return createIf(
+                    () => innerShow.value,
+                    () => {
+                      return document.createTextNode('content')
+                    },
+                  )
+                },
+              )
+            },
+          })
+        },
+      }).render()
+
+      expect(html()).toBe('fallback<!--if--><!--slot-->')
+
+      outerShow.value = true
+      await nextTick()
+      expect(html()).toBe('fallback<!--if--><!--if--><!--slot-->')
+
+      innerShow.value = true
+      await nextTick()
+      expect(html()).toBe('content<!--if--><!--if--><!--slot-->')
+
+      innerShow.value = false
+      await nextTick()
+      expect(html()).toBe('fallback<!--if--><!--if--><!--slot-->')
+
+      outerShow.value = false
+      await nextTick()
+      expect(html()).toBe('fallback<!--if--><!--slot-->')
+
+      outerShow.value = true
+      await nextTick()
+      expect(html()).toBe('fallback<!--if--><!--if--><!--slot-->')
+
+      innerShow.value = true
+      await nextTick()
+      expect(html()).toBe('content<!--if--><!--if--><!--slot-->')
+    })
   })
 })
index 50a453dc483a21e6dca96c0c7961997f770f995e..2a78048f8b26bab135624c70b7c3f0966d7d2a5f 100644 (file)
@@ -67,10 +67,9 @@ export class DynamicFragment extends VaporFragment {
 
     if (this.fallback && !isValidBlock(this.nodes)) {
       parent && remove(this.nodes, parent)
-      // if current nodes is a DynamicFragment, call its update with the fallback
-      // to handle nested dynamic fragment
-      if (this.nodes instanceof DynamicFragment) {
-        this.nodes.update(this.fallback)
+      // handle nested dynamic fragment
+      if (isFragment(this.nodes)) {
+        renderFallback(this.nodes, this.fallback, key)
       } else {
         this.nodes =
           (this.scope || (this.scope = new EffectScope())).run(this.fallback) ||
@@ -83,6 +82,22 @@ export class DynamicFragment extends VaporFragment {
   }
 }
 
+function renderFallback(
+  fragment: VaporFragment,
+  fallback: BlockFn,
+  key: any,
+): void {
+  if (fragment instanceof DynamicFragment) {
+    const nodes = fragment.nodes
+    if (isFragment(nodes)) {
+      renderFallback(nodes, fallback, key)
+    } else {
+      if (!fragment.fallback) fragment.fallback = fallback
+      fragment.update(fragment.fallback, key)
+    }
+  }
+}
+
 export function isFragment(val: NonNullable<unknown>): val is VaporFragment {
   return val instanceof VaporFragment
 }