]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: Merge branch 'minor' into edison/testVapor
authordaiwei <daiwei521@126.com>
Mon, 8 Sep 2025 07:18:06 +0000 (15:18 +0800)
committerdaiwei <daiwei521@126.com>
Mon, 8 Sep 2025 07:18:06 +0000 (15:18 +0800)
1  2 
packages/compiler-sfc/src/compileScript.ts
packages/runtime-core/src/apiAsyncComponent.ts
packages/runtime-core/src/index.ts
packages/runtime-core/src/renderer.ts
packages/runtime-vapor/__tests__/componentSlots.spec.ts
packages/runtime-vapor/src/apiTemplateRef.ts
packages/runtime-vapor/src/block.ts
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/directives/vShow.ts

index 686747458e0de2a7d5d7c82464fb5b0635e9126d,36ac6547709377b52f1a92b7ed534d675f4dec05..fe413753548007294c871ea0108ad362eace37e6
@@@ -976,15 -1013,14 +1013,19 @@@ export function compileScript
  
    // <script setup> components are closed by default. If the user did not
    // explicitly call `defineExpose`, call expose() with no args.
-   const exposeCall =
-     ctx.hasDefineExposeCall || options.inlineTemplate ? `` : `  __expose();\n`
+   if (!ctx.hasDefineExposeCall && !inlineMode)
+     setupPreambleLines.push(`__expose();`)
+   const setupPreamble = setupPreambleLines.length
+     ? `  ${setupPreambleLines.join('\n  ')}\n`
+     : ''
    // wrap setup code with function.
    if (ctx.isTS) {
 +    // in SSR, always use defineComponent, so __vapor flag is required
 +    if (ssr && vapor) {
 +      runtimeOptions += `\n  __vapor: true,`
 +    }
 +
      // for TS, make sure the exported type is still valid type with
      // correct props information
      // we have to use object spread for types to be merged properly
index 8841f669b7c53aed93eb7cc9b282c120b554c789,1ff9fa067e7e75cfe5d4baea4ebba83f0d71816a..ac579f6fb8ebd32d6265cda9040644fca1c93fc6
@@@ -69,29 -124,31 +69,32 @@@ export function defineAsyncComponent
  
      __asyncHydrate(el, instance, hydrate) {
        let patched = false
+       ;(instance.bu || (instance.bu = [])).push(() => (patched = true))
+       const performHydrate = () => {
+         // skip hydration if the component has been patched
+         if (patched) {
+           if (__DEV__) {
++            const resolvedComp = getResolvedComp()
+             warn(
+               `Skipping lazy hydration for component '${getComponentName(resolvedComp!) || resolvedComp!.__file}': ` +
+                 `it was updated before lazy hydration performed.`,
+             )
+           }
+           return
+         }
+         hydrate()
+       }
        const doHydrate = hydrateStrategy
          ? () => {
-             const performHydrate = () => {
-               // skip hydration if the component has been patched
-               if (__DEV__ && patched) {
-                 warn(
-                   `Skipping lazy hydration for component '${getComponentName(getResolvedComp()!)}': ` +
-                     `it was updated before lazy hydration performed.`,
-                 )
-                 return
-               }
-               hydrate()
-             }
              const teardown = hydrateStrategy(performHydrate, cb =>
                forEachElement(el, cb),
              )
              if (teardown) {
                ;(instance.bum || (instance.bum = [])).push(teardown)
              }
-             ;(instance.u || (instance.u = [])).push(() => (patched = true))
            }
-         : hydrate
+         : performHydrate
 -      if (resolvedComp) {
 +      if (getResolvedComp()) {
          doHydrate()
        } else {
          load().then(() => !instance.isUnmounted && doHydrate())
Simple merge
Simple merge
index ea9c07dc025163f7e5cdf3a72792cd31ba4088bc,ff7aa56d05529acd72b10b05d3c7878b1e5299a9..fd25fa81a00ca303ebc3ed7f60715a92f63f83e6
@@@ -13,23 -10,13 +13,24 @@@ import 
    insert,
    prepend,
    renderEffect,
+   setInsertionState,
    template,
 +  vaporInteropPlugin,
  } from '../src'
 -import { currentInstance, nextTick, ref } from '@vue/runtime-dom'
 +import {
 +  type Ref,
 +  createApp,
 +  createSlots,
 +  currentInstance,
 +  h,
 +  nextTick,
 +  ref,
 +  renderSlot,
 +  toDisplayString,
 +} from '@vue/runtime-dom'
  import { makeRender } from './_utils'
  import type { DynamicSlot } from '../src/componentSlots'
 -import { setElementText } from '../src/dom/prop'
 +import { setElementText, setText } from '../src/dom/prop'
  
  const define = makeRender<any>()
  
@@@ -554,2152 -504,34 +555,2182 @@@ describe('component: slots', () => 
        expect(host.innerHTML).toBe('<div><h1></h1><!--slot--></div>')
      })
  
 +    test('render fallback when slot content is not valid', async () => {
 +      const Child = {
 +        setup() {
 +          return createSlot('default', null, () =>
 +            document.createTextNode('fallback'),
 +          )
 +        },
 +      }
 +
 +      const { html } = define({
 +        setup() {
 +          return createComponent(Child, null, {
 +            default: () => {
 +              return template('<!--comment-->')()
 +            },
 +          })
 +        },
 +      }).render()
 +
 +      expect(html()).toBe('fallback<!--slot-->')
 +    })
 +
 +    test('render fallback when v-if condition is false', async () => {
 +      const Child = {
 +        setup() {
 +          return createSlot('default', null, () =>
 +            document.createTextNode('fallback'),
 +          )
 +        },
 +      }
 +
 +      const toggle = ref(false)
 +
 +      const { html } = define({
 +        setup() {
 +          return createComponent(Child, null, {
 +            default: () => {
 +              return createIf(
 +                () => toggle.value,
 +                () => {
 +                  return document.createTextNode('content')
 +                },
 +              )
 +            },
 +          })
 +        },
 +      }).render()
 +
 +      expect(html()).toBe('fallback<!--if--><!--slot-->')
 +
 +      toggle.value = true
 +      await nextTick()
 +      expect(html()).toBe('content<!--if--><!--slot-->')
 +
 +      toggle.value = false
 +      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-->')
 +    })
 +
 +    test('render fallback with v-for', async () => {
 +      const Child = {
 +        setup() {
 +          return createSlot('default', null, () =>
 +            document.createTextNode('fallback'),
 +          )
 +        },
 +      }
 +
 +      const items = ref<number[]>([1])
 +      const { html } = define({
 +        setup() {
 +          return createComponent(Child, null, {
 +            default: () => {
 +              const n2 = createFor(
 +                () => items.value,
 +                for_item0 => {
 +                  const n4 = template('<span> </span>')() as any
 +                  const x4 = child(n4) as any
 +                  renderEffect(() =>
 +                    setText(x4, toDisplayString(for_item0.value)),
 +                  )
 +                  return n4
 +                },
 +              )
 +              return n2
 +            },
 +          })
 +        },
 +      }).render()
 +
 +      expect(html()).toBe('<span>1</span><!--for--><!--slot-->')
 +
 +      items.value.pop()
 +      await nextTick()
 +      expect(html()).toBe('fallback<!--for--><!--slot-->')
 +
 +      items.value.pop()
 +      await nextTick()
 +      expect(html()).toBe('fallback<!--for--><!--slot-->')
 +
 +      items.value.push(2)
 +      await nextTick()
 +      expect(html()).toBe('<span>2</span><!--for--><!--slot-->')
 +    })
 +
 +    test('render fallback with v-for (empty source)', async () => {
 +      const Child = {
 +        setup() {
 +          return createSlot('default', null, () =>
 +            document.createTextNode('fallback'),
 +          )
 +        },
 +      }
 +
 +      const items = ref<number[]>([])
 +      const { html } = define({
 +        setup() {
 +          return createComponent(Child, null, {
 +            default: () => {
 +              const n2 = createFor(
 +                () => items.value,
 +                for_item0 => {
 +                  const n4 = template('<span> </span>')() as any
 +                  const x4 = child(n4) as any
 +                  renderEffect(() =>
 +                    setText(x4, toDisplayString(for_item0.value)),
 +                  )
 +                  return n4
 +                },
 +              )
 +              return n2
 +            },
 +          })
 +        },
 +      }).render()
 +
 +      expect(html()).toBe('fallback<!--for--><!--slot-->')
 +
 +      items.value.push(1)
 +      await nextTick()
 +      expect(html()).toBe('<span>1</span><!--for--><!--slot-->')
 +
 +      items.value.pop()
 +      await nextTick()
 +      expect(html()).toBe('fallback<!--for--><!--slot-->')
 +
 +      items.value.pop()
 +      await nextTick()
 +      expect(html()).toBe('fallback<!--for--><!--slot-->')
 +
 +      items.value.push(2)
 +      await nextTick()
 +      expect(html()).toBe('<span>2</span><!--for--><!--slot-->')
 +    })
 +  })
 +
 +  describe('forwarded slot', () => {
 +    test('should work', async () => {
 +      const Child = defineVaporComponent({
 +        setup() {
 +          return createSlot('foo', null)
 +        },
 +      })
 +      const Parent = defineVaporComponent({
 +        setup() {
 +          const createForwardedSlot = forwardedSlotCreator()
 +          const n2 = createComponent(
 +            Child,
 +            null,
 +            {
 +              foo: () => {
 +                return createForwardedSlot('foo', null)
 +              },
 +            },
 +            true,
 +          )
 +          return n2
 +        },
 +      })
 +
 +      const foo = ref('foo')
 +      const { host } = define({
 +        setup() {
 +          const n2 = createComponent(
 +            Parent,
 +            null,
 +            {
 +              foo: () => {
 +                const n0 = template(' ')() as any
 +                renderEffect(() => setText(n0, foo.value))
 +                return n0
 +              },
 +            },
 +            true,
 +          )
 +          return n2
 +        },
 +      }).render()
 +
 +      expect(host.innerHTML).toBe('foo<!--slot--><!--slot-->')
 +
 +      foo.value = 'bar'
 +      await nextTick()
 +      expect(host.innerHTML).toBe('bar<!--slot--><!--slot-->')
 +    })
 +
 +    test('mixed with non-forwarded slot', async () => {
 +      const Child = defineVaporComponent({
 +        setup() {
 +          return [createSlot('foo', null)]
 +        },
 +      })
 +      const Parent = defineVaporComponent({
 +        setup() {
 +          const createForwardedSlot = forwardedSlotCreator()
 +          const n2 = createComponent(Child, null, {
 +            foo: () => {
 +              const n0 = createForwardedSlot('foo', null)
 +              return n0
 +            },
 +          })
 +          const n3 = createSlot('default', null)
 +          return [n2, n3]
 +        },
 +      })
 +
 +      const foo = ref('foo')
 +      const { host } = define({
 +        setup() {
 +          const n2 = createComponent(
 +            Parent,
 +            null,
 +            {
 +              foo: () => {
 +                const n0 = template(' ')() as any
 +                renderEffect(() => setText(n0, foo.value))
 +                return n0
 +              },
 +              default: () => {
 +                const n3 = template(' ')() as any
 +                renderEffect(() => setText(n3, foo.value))
 +                return n3
 +              },
 +            },
 +            true,
 +          )
 +          return n2
 +        },
 +      }).render()
 +
 +      expect(host.innerHTML).toBe('foo<!--slot--><!--slot-->foo<!--slot-->')
 +
 +      foo.value = 'bar'
 +      await nextTick()
 +      expect(host.innerHTML).toBe('bar<!--slot--><!--slot-->bar<!--slot-->')
 +    })
 +
 +    describe('vdom interop', () => {
 +      const createVaporSlot = (fallbackText = 'fallback') => {
 +        return defineVaporComponent({
 +          setup() {
 +            const n0 = createSlot('foo', null, () => {
 +              const n2 = template(`<div>${fallbackText}</div>`)()
 +              return n2
 +            })
 +            return n0
 +          },
 +        })
 +      }
 +
 +      const createVdomSlot = (fallbackText = 'fallback') => {
 +        return {
 +          render(this: any) {
 +            return renderSlot(this.$slots, 'foo', {}, () => [
 +              h('div', fallbackText),
 +            ])
 +          },
 +        }
 +      }
 +
 +      const createVaporForwardedSlot = (
 +        targetComponent: any,
 +        fallbackText?: string,
 +      ) => {
 +        return defineVaporComponent({
 +          setup() {
 +            const createForwardedSlot = forwardedSlotCreator()
 +            const n2 = createComponent(
 +              targetComponent,
 +              null,
 +              {
 +                foo: () => {
 +                  return fallbackText
 +                    ? createForwardedSlot('foo', null, () => {
 +                        const n2 = template(`<div>${fallbackText}</div>`)()
 +                        return n2
 +                      })
 +                    : createForwardedSlot('foo', null)
 +                },
 +              },
 +              true,
 +            )
 +            return n2
 +          },
 +        })
 +      }
 +
 +      const createVdomForwardedSlot = (
 +        targetComponent: any,
 +        fallbackText?: string,
 +      ) => {
 +        return {
 +          render(this: any) {
 +            return h(targetComponent, null, {
 +              foo: () => [
 +                fallbackText
 +                  ? renderSlot(this.$slots, 'foo', {}, () => [
 +                      h('div', fallbackText),
 +                    ])
 +                  : renderSlot(this.$slots, 'foo'),
 +              ],
 +              _: 3 /* FORWARDED */,
 +            })
 +          },
 +        }
 +      }
 +
 +      const createMultipleVaporForwardedSlots = (
 +        targetComponent: any,
 +        count: number,
 +      ) => {
 +        let current = targetComponent
 +        for (let i = 0; i < count; i++) {
 +          current = createVaporForwardedSlot(current)
 +        }
 +        return current
 +      }
 +
 +      const createMultipleVdomForwardedSlots = (
 +        targetComponent: any,
 +        count: number,
 +      ) => {
 +        let current = targetComponent
 +        for (let i = 0; i < count; i++) {
 +          current = createVdomForwardedSlot(current)
 +        }
 +        return current
 +      }
 +
 +      const createTestApp = (
 +        rootComponent: any,
 +        foo: Ref<string>,
 +        show: Ref<Boolean>,
 +      ) => {
 +        return {
 +          setup() {
 +            return () =>
 +              h(
 +                rootComponent,
 +                null,
 +                createSlots({ _: 2 /* DYNAMIC */ } as any, [
 +                  show.value
 +                    ? {
 +                        name: 'foo',
 +                        fn: () => [h('span', foo.value)],
 +                        key: '0',
 +                      }
 +                    : undefined,
 +                ]),
 +              )
 +          },
 +        }
 +      }
 +
 +      const createEmptyTestApp = (rootComponent: any) => {
 +        return {
 +          setup() {
 +            return () => h(rootComponent)
 +          },
 +        }
 +      }
 +
 +      test('vdom slot > vapor forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VaporSlot,
 +          'forwarded fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>forwarded fallback</div><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VdomSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VdomSlot,
 +          'forwarded fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>forwarded fallback</div>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
 +        const VaporForwardedSlot = createVaporForwardedSlot(VdomForwardedSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vdom forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VdomForwardedSlot,
 +          'forwarded fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>forwarded fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VdomForwardedSlotWithFallback,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot(empty) > vapor forwarded slot > vdom forwarded slot(with fallback) > vapor slot', async () => {
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VdomForwardedSlotWithFallback,
 +        )
 +        const App = createEmptyTestApp(VaporForwardedSlot)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<div>vdom fallback</div>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
 +        const VaporForwardedSlot = createVaporForwardedSlot(VdomForwardedSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vdom forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VdomForwardedSlot,
 +          'vapor fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VdomSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VdomForwardedSlotWithFallback,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot (multiple) > vdom forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
 +        const VaporForwardedSlot = createMultipleVaporForwardedSlots(
 +          VdomForwardedSlot,
 +          3,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot--><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot (multiple) > vdom forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VdomSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createMultipleVaporForwardedSlots(
 +          VdomForwardedSlotWithFallback,
 +          3,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe(
 +          '<div>vdom fallback</div><!--slot--><!--slot-->',
 +        )
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot > vapor forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporForwardedSlot)
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot (multiple) > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
 +        const VdomForwardedSlot = createMultipleVdomForwardedSlots(
 +          VaporForwardedSlot,
 +          3,
 +        )
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot (multiple) > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VaporSlot,
 +          'vapor fallback',
 +        )
 +        const VdomForwardedSlot = createMultipleVdomForwardedSlots(
 +          VaporForwardedSlot,
 +          3,
 +        )
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot1 = createMultipleVaporForwardedSlots(
 +          VdomSlot,
 +          2,
 +        )
 +        const App = createTestApp(VaporForwardedSlot1, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot2 = createVaporForwardedSlot(VdomSlot)
 +        const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
 +          VaporForwardedSlot2,
 +          'vapor1 fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor1 fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
 +          VdomSlot,
 +          'vapor2 fallback',
 +        )
 +        const VaporForwardedSlot1 = createVaporForwardedSlot(
 +          VaporForwardedSlot2WithFallback,
 +        )
 +        const App = createTestApp(VaporForwardedSlot1, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor2 fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vapor forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot2 = createVaporForwardedSlot(VaporSlot)
 +        const VaporForwardedSlot1 =
 +          createVaporForwardedSlot(VaporForwardedSlot2)
 +        const App = createTestApp(VaporForwardedSlot1, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot--><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
 +          VdomSlot,
 +          'vapor2 fallback',
 +        )
 +        const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
 +          VaporForwardedSlot2WithFallback,
 +          'vapor1 fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor1 fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
 +          VaporSlot,
 +          'vapor2 fallback',
 +        )
 +        const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
 +          VaporForwardedSlot2WithFallback,
 +          'vapor1 fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe(
 +          '<div>vapor1 fallback</div><!--slot--><!--slot-->',
 +        )
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom2 fallback',
 +        )
 +        const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot2WithFallback,
 +          'vdom1 fallback',
 +        )
 +        const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom1 fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
 +          VdomSlot,
 +          'vdom2 fallback',
 +        )
 +        const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot2WithFallback,
 +          'vdom1 fallback',
 +        )
 +        const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom1 fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) (multiple) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot3WithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom3 fallback',
 +        )
 +        const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot3WithFallback,
 +          'vdom2 fallback',
 +        )
 +        const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot2WithFallback,
 +          'vdom1 fallback',
 +        )
 +        const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom1 fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +    })
 +  })
 +
 +  describe('forwarded slot', () => {
 +    test('should work', async () => {
 +      const Child = defineVaporComponent({
 +        setup() {
 +          return createSlot('foo', null)
 +        },
 +      })
 +      const Parent = defineVaporComponent({
 +        setup() {
 +          const createForwardedSlot = forwardedSlotCreator()
 +          const n2 = createComponent(
 +            Child,
 +            null,
 +            {
 +              foo: () => {
 +                return createForwardedSlot('foo', null)
 +              },
 +            },
 +            true,
 +          )
 +          return n2
 +        },
 +      })
 +
 +      const foo = ref('foo')
 +      const { host } = define({
 +        setup() {
 +          const n2 = createComponent(
 +            Parent,
 +            null,
 +            {
 +              foo: () => {
 +                const n0 = template(' ')() as any
 +                renderEffect(() => setText(n0, foo.value))
 +                return n0
 +              },
 +            },
 +            true,
 +          )
 +          return n2
 +        },
 +      }).render()
 +
 +      expect(host.innerHTML).toBe('foo<!--slot--><!--slot-->')
 +
 +      foo.value = 'bar'
 +      await nextTick()
 +      expect(host.innerHTML).toBe('bar<!--slot--><!--slot-->')
 +    })
 +
 +    test('mixed with non-forwarded slot', async () => {
 +      const Child = defineVaporComponent({
 +        setup() {
 +          return [createSlot('foo', null)]
 +        },
 +      })
 +      const Parent = defineVaporComponent({
 +        setup() {
 +          const createForwardedSlot = forwardedSlotCreator()
 +          const n2 = createComponent(Child, null, {
 +            foo: () => {
 +              const n0 = createForwardedSlot('foo', null)
 +              return n0
 +            },
 +          })
 +          const n3 = createSlot('default', null)
 +          return [n2, n3]
 +        },
 +      })
 +
 +      const foo = ref('foo')
 +      const { host } = define({
 +        setup() {
 +          const n2 = createComponent(
 +            Parent,
 +            null,
 +            {
 +              foo: () => {
 +                const n0 = template(' ')() as any
 +                renderEffect(() => setText(n0, foo.value))
 +                return n0
 +              },
 +              default: () => {
 +                const n3 = template(' ')() as any
 +                renderEffect(() => setText(n3, foo.value))
 +                return n3
 +              },
 +            },
 +            true,
 +          )
 +          return n2
 +        },
 +      }).render()
 +
 +      expect(host.innerHTML).toBe('foo<!--slot--><!--slot-->foo<!--slot-->')
 +
 +      foo.value = 'bar'
 +      await nextTick()
 +      expect(host.innerHTML).toBe('bar<!--slot--><!--slot-->bar<!--slot-->')
 +    })
 +
 +    describe('vdom interop', () => {
 +      const createVaporSlot = (fallbackText = 'fallback') => {
 +        return defineVaporComponent({
 +          setup() {
 +            const n0 = createSlot('foo', null, () => {
 +              const n2 = template(`<div>${fallbackText}</div>`)()
 +              return n2
 +            })
 +            return n0
 +          },
 +        })
 +      }
 +
 +      const createVdomSlot = (fallbackText = 'fallback') => {
 +        return {
 +          render(this: any) {
 +            return renderSlot(this.$slots, 'foo', {}, () => [
 +              h('div', fallbackText),
 +            ])
 +          },
 +        }
 +      }
 +
 +      const createVaporForwardedSlot = (
 +        targetComponent: any,
 +        fallbackText?: string,
 +      ) => {
 +        return defineVaporComponent({
 +          setup() {
 +            const createForwardedSlot = forwardedSlotCreator()
 +            const n2 = createComponent(
 +              targetComponent,
 +              null,
 +              {
 +                foo: () => {
 +                  return fallbackText
 +                    ? createForwardedSlot('foo', null, () => {
 +                        const n2 = template(`<div>${fallbackText}</div>`)()
 +                        return n2
 +                      })
 +                    : createForwardedSlot('foo', null)
 +                },
 +              },
 +              true,
 +            )
 +            return n2
 +          },
 +        })
 +      }
 +
 +      const createVdomForwardedSlot = (
 +        targetComponent: any,
 +        fallbackText?: string,
 +      ) => {
 +        return {
 +          render(this: any) {
 +            return h(targetComponent, null, {
 +              foo: () => [
 +                fallbackText
 +                  ? renderSlot(this.$slots, 'foo', {}, () => [
 +                      h('div', fallbackText),
 +                    ])
 +                  : renderSlot(this.$slots, 'foo'),
 +              ],
 +              _: 3 /* FORWARDED */,
 +            })
 +          },
 +        }
 +      }
 +
 +      const createMultipleVaporForwardedSlots = (
 +        targetComponent: any,
 +        count: number,
 +      ) => {
 +        let current = targetComponent
 +        for (let i = 0; i < count; i++) {
 +          current = createVaporForwardedSlot(current)
 +        }
 +        return current
 +      }
 +
 +      const createMultipleVdomForwardedSlots = (
 +        targetComponent: any,
 +        count: number,
 +      ) => {
 +        let current = targetComponent
 +        for (let i = 0; i < count; i++) {
 +          current = createVdomForwardedSlot(current)
 +        }
 +        return current
 +      }
 +
 +      const createTestApp = (
 +        rootComponent: any,
 +        foo: Ref<string>,
 +        show: Ref<Boolean>,
 +      ) => {
 +        return {
 +          setup() {
 +            return () =>
 +              h(
 +                rootComponent,
 +                null,
 +                createSlots({ _: 2 /* DYNAMIC */ } as any, [
 +                  show.value
 +                    ? {
 +                        name: 'foo',
 +                        fn: () => [h('span', foo.value)],
 +                        key: '0',
 +                      }
 +                    : undefined,
 +                ]),
 +              )
 +          },
 +        }
 +      }
 +
 +      const createEmptyTestApp = (rootComponent: any) => {
 +        return {
 +          setup() {
 +            return () => h(rootComponent)
 +          },
 +        }
 +      }
 +
 +      test('vdom slot > vapor forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VaporSlot,
 +          'forwarded fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>forwarded fallback</div><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VdomSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VdomSlot,
 +          'forwarded fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>forwarded fallback</div>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
 +        const VaporForwardedSlot = createVaporForwardedSlot(VdomForwardedSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vdom forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VdomForwardedSlot,
 +          'forwarded fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>forwarded fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VdomForwardedSlotWithFallback,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot(empty) > vapor forwarded slot > vdom forwarded slot(with fallback) > vapor slot', async () => {
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VdomForwardedSlotWithFallback,
 +        )
 +        const App = createEmptyTestApp(VaporForwardedSlot)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<div>vdom fallback</div>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
 +        const VaporForwardedSlot = createVaporForwardedSlot(VdomForwardedSlot)
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vdom forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
 +        const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
 +          VdomForwardedSlot,
 +          'vapor fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vdom forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VdomSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VdomForwardedSlotWithFallback,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot (multiple) > vdom forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
 +        const VaporForwardedSlot = createMultipleVaporForwardedSlots(
 +          VdomForwardedSlot,
 +          3,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot--><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot (multiple) > vdom forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
 +          VdomSlot,
 +          'vdom fallback',
 +        )
 +        const VaporForwardedSlot = createMultipleVaporForwardedSlots(
 +          VdomForwardedSlotWithFallback,
 +          3,
 +        )
 +        const App = createTestApp(VaporForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe(
 +          '<div>vdom fallback</div><!--slot--><!--slot-->',
 +        )
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot > vapor forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
 +        const VdomForwardedSlot = createVdomForwardedSlot(VaporForwardedSlot)
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot (multiple) > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
 +        const VdomForwardedSlot = createMultipleVdomForwardedSlots(
 +          VaporForwardedSlot,
 +          3,
 +        )
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot (multiple) > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot = createVaporForwardedSlot(
 +          VaporSlot,
 +          'vapor fallback',
 +        )
 +        const VdomForwardedSlot = createMultipleVdomForwardedSlots(
 +          VaporForwardedSlot,
 +          3,
 +        )
 +        const App = createTestApp(VdomForwardedSlot, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot1 = createMultipleVaporForwardedSlots(
 +          VdomSlot,
 +          2,
 +        )
 +        const App = createTestApp(VaporForwardedSlot1, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot2 = createVaporForwardedSlot(VdomSlot)
 +        const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
 +          VaporForwardedSlot2,
 +          'vapor1 fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor1 fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
 +          VdomSlot,
 +          'vapor2 fallback',
 +        )
 +        const VaporForwardedSlot1 = createVaporForwardedSlot(
 +          VaporForwardedSlot2WithFallback,
 +        )
 +        const App = createTestApp(VaporForwardedSlot1, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor2 fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot > vapor forwarded slot > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot2 = createVaporForwardedSlot(VaporSlot)
 +        const VaporForwardedSlot1 =
 +          createVaporForwardedSlot(VaporForwardedSlot2)
 +        const App = createTestApp(VaporForwardedSlot1, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>fallback</div><!--slot--><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
 +          VdomSlot,
 +          'vapor2 fallback',
 +        )
 +        const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
 +          VaporForwardedSlot2WithFallback,
 +          'vapor1 fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vapor1 fallback</div><!--slot-->')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot-->')
 +      })
 +
 +      test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
 +          VaporSlot,
 +          'vapor2 fallback',
 +        )
 +        const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
 +          VaporForwardedSlot2WithFallback,
 +          'vapor1 fallback',
 +        )
 +        const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span><!--slot--><!--slot-->')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe(
 +          '<div>vapor1 fallback</div><!--slot--><!--slot-->',
 +        )
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span><!--slot--><!--slot-->')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom2 fallback',
 +        )
 +        const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot2WithFallback,
 +          'vdom1 fallback',
 +        )
 +        const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom1 fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) > vdom slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VdomSlot = createVdomSlot()
 +        const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
 +          VdomSlot,
 +          'vdom2 fallback',
 +        )
 +        const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot2WithFallback,
 +          'vdom1 fallback',
 +        )
 +        const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom1 fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +
 +      test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) (multiple) > vapor slot', async () => {
 +        const foo = ref('foo')
 +        const show = ref(true)
 +
 +        const VaporSlot = createVaporSlot()
 +        const VdomForwardedSlot3WithFallback = createVdomForwardedSlot(
 +          VaporSlot,
 +          'vdom3 fallback',
 +        )
 +        const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot3WithFallback,
 +          'vdom2 fallback',
 +        )
 +        const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
 +          VdomForwardedSlot2WithFallback,
 +          'vdom1 fallback',
 +        )
 +        const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
 +
 +        const root = document.createElement('div')
 +        createApp(App).use(vaporInteropPlugin).mount(root)
 +        expect(root.innerHTML).toBe('<span>foo</span>')
 +
 +        foo.value = 'bar'
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +
 +        show.value = false
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<div>vdom1 fallback</div>')
 +
 +        show.value = true
 +        await nextTick()
 +        expect(root.innerHTML).toBe('<span>bar</span>')
 +      })
 +    })
++
+     test('consecutive slots with insertion state', async () => {
+       const { component: Child } = define({
+         setup() {
+           const n2 = template('<div><div>baz</div></div>', true)() as any
+           setInsertionState(n2, 0)
+           createSlot('default', null)
+           setInsertionState(n2, 0)
+           createSlot('foo', null)
+           return n2
+         },
+       })
+       const { html } = define({
+         setup() {
+           return createComponent(Child, null, {
+             default: () => template('default')(),
+             foo: () => template('foo')(),
+           })
+         },
+       }).render()
+       expect(html()).toBe(
+         `<div>` +
+           `default<!--slot-->` +
+           `foo<!--slot-->` +
+           `<div>baz</div>` +
+           `</div>`,
+       )
+     })
    })
  })
index 3a34f5bd8365a40f7e0e24ff76fe3d497f4d8c3c,a14f373e7def428d3dc890c5ff61ddcfeb930077..4c7305f992bdf821716d47c41ef16d12c292172a
@@@ -9,7 -9,7 +9,8 @@@ import 
    ErrorCodes,
    type SchedulerJob,
    callWithErrorHandling,
+   createCanSetSetupRefChecker,
 +  isAsyncWrapper,
    queuePostFlushCb,
    warn,
  } from '@vue/runtime-dom'
index 75679004c38e236069d3394f8c45e6ac9ecf1299,ba84161a71b2430314f5e87244b848a059350c61..b980b39991b987d19ef6150b8f78ada478d3a578
@@@ -68,28 -105,13 +68,28 @@@ export function isValidBlock(block: Blo
  
  export function insert(
    block: Block,
-   parent: ParentNode,
+   parent: ParentNode & { $anchor?: Node | null },
    anchor: Node | null | 0 = null, // 0 means prepend
 +  parentSuspense?: any, // TODO Suspense
  ): void {
 -  anchor = anchor === 0 ? parent.$anchor || parent.firstChild : anchor
 +  anchor = anchor === 0 ? child(parent) : anchor
    if (block instanceof Node) {
      if (!isHydrating) {
 -      parent.insertBefore(block, anchor)
 +      // only apply transition on Element nodes
 +      if (
 +        block instanceof Element &&
 +        (block as TransitionBlock).$transition &&
 +        !(block as TransitionBlock).$transition!.disabled
 +      ) {
 +        performTransitionEnter(
 +          block,
 +          (block as TransitionBlock).$transition as TransitionHooks,
 +          () => parent.insertBefore(block, anchor as Node),
 +          parentSuspense,
 +        )
 +      } else {
 +        parent.insertBefore(block, anchor)
 +      }
      }
    } else if (isVaporComponent(block)) {
      if (block.isMounted) {
index 13963db45f9e647ab1828d222678ae40eb5028a4,08fd881e9596ea578114a8c6d1b64ce28bddde10..a60a24e1124c429a43a0850ee5942a6f5beacba1
@@@ -191,39 -180,6 +209,21 @@@ export function createComponent
      return frag
    }
  
-   if (
-     isSingleRoot &&
-     component.inheritAttrs !== false &&
-     isVaporComponent(currentInstance) &&
-     currentInstance.hasFallthrough
-   ) {
-     // check if we are the single root of the parent
-     // if yes, inject parent attrs as dynamic props source
-     const attrs = currentInstance.attrs
-     if (rawProps) {
-       ;((rawProps as RawProps).$ || ((rawProps as RawProps).$ = [])).push(
-         () => attrs,
-       )
-     } else {
-       rawProps = { $: [() => attrs] } as RawProps
-     }
-   }
 +  // teleport
 +  if (isVaporTeleport(component)) {
 +    const frag = component.process(rawProps!, rawSlots!)
 +    if (!isHydrating) {
 +      if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor)
 +    } else {
 +      frag.hydrate()
 +      if (_insertionAnchor !== undefined) {
 +        advanceHydrationNode(_insertionParent!)
 +      }
 +    }
 +
 +    return frag as any
 +  }
 +
    const instance = new VaporComponentInstance(
      component,
      rawProps as RawProps,
index 406b372c20c255d34112899bc99f8793b0aac347,6ed28dfddfedff207e33d050c94a80b87430e0fd..d7dd22d6781a6e04082e6af0aa38ac510276c82c
@@@ -6,9 -6,8 +6,9 @@@ import 
  } from '@vue/runtime-dom'
  import { renderEffect } from '../renderEffect'
  import { isVaporComponent } from '../component'
 -import { type Block, DynamicFragment, VaporFragment } from '../block'
 +import type { Block, TransitionBlock } from '../block'
  import { isArray } from '@vue/shared'
- import { DynamicFragment } from '../fragment'
++import { DynamicFragment, VaporFragment } from '../fragment'
  
  export function applyVShow(target: Block, source: () => any): void {
    if (isVaporComponent(target)) {
@@@ -40,7 -46,9 +47,10 @@@ function setDisplay(target: Block, valu
    if (target instanceof DynamicFragment) {
      return setDisplay(target.nodes, value)
    }
 +  const { $transition } = target as TransitionBlock
+   if (target instanceof VaporFragment && target.insert) {
+     return setDisplay(target.nodes, value)
+   }
    if (target instanceof Element) {
      const el = target as VShowElement
      if (!(vShowOriginalDisplay in el)) {