]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-vapor): properly handle dynamic slot work with v-if (#12660)
authoredison <daiwei521@126.com>
Wed, 29 Jan 2025 02:21:30 +0000 (10:21 +0800)
committerGitHub <noreply@github.com>
Wed, 29 Jan 2025 02:21:30 +0000 (10:21 +0800)
packages/runtime-vapor/__tests__/componentSlots.spec.ts
packages/runtime-vapor/src/componentSlots.ts

index f4ff0c31cba2ff7a2039260552d8331ba75865ba..452efa9bc330810480adde68ba62e21ddf96c95a 100644 (file)
@@ -15,6 +15,7 @@ import {
 } from '../src'
 import { currentInstance, nextTick, ref } from '@vue/runtime-dom'
 import { makeRender } from './_utils'
+import type { DynamicSlot } from '../src/componentSlots'
 
 const define = makeRender<any>()
 
@@ -468,5 +469,39 @@ describe('component: slots', () => {
       await nextTick()
       expect(html()).toBe('content<!--if--><!--slot-->')
     })
+
+    test('dynamic slot work with v-if', async () => {
+      const val = ref('header')
+      const toggle = ref(false)
+
+      const Comp = defineVaporComponent(() => {
+        const n0 = template('<div></div>')()
+        prepend(n0 as any as ParentNode, createSlot('header', null))
+        return n0
+      })
+
+      const { host } = define(() => {
+        // dynamic slot
+        return createComponent(Comp, null, {
+          $: [
+            () =>
+              (toggle.value
+                ? {
+                    name: val.value,
+                    fn: () => {
+                      return template('<h1></h1>')()
+                    },
+                  }
+                : void 0) as DynamicSlot,
+          ],
+        })
+      }).render()
+
+      expect(host.innerHTML).toBe('<div><!--slot--></div>')
+
+      toggle.value = true
+      await nextTick()
+      expect(host.innerHTML).toBe('<div><h1></h1><!--slot--></div>')
+    })
   })
 })
index cc6a825222e1b7acf73aed175b5e8f3723170d9e..bf3f4ae2de4ef8ed1800493dfb64f775ed4a7fb8 100644 (file)
@@ -70,12 +70,14 @@ export function getSlot(
       source = dynamicSources[i]
       if (isFunction(source)) {
         const slot = source()
-        if (isArray(slot)) {
-          for (const s of slot) {
-            if (s.name === key) return s.fn
+        if (slot) {
+          if (isArray(slot)) {
+            for (const s of slot) {
+              if (s.name === key) return s.fn
+            }
+          } else if (slot.name === key) {
+            return slot.fn
           }
-        } else if (slot.name === key) {
-          return slot.fn
         }
       } else if (hasOwn(source, key)) {
         return source[key]