From 139546231f156764f69609b920e5995b6df66802 Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 4 Jul 2025 09:44:04 +0800 Subject: [PATCH] fix(runtime-vapor): render slot fallback if no content is provided --- packages/runtime-vapor/__tests__/_utils.ts | 54 ++++++++++++++++++- .../__tests__/vdomInterop.spec.ts | 29 ++++++++++ packages/runtime-vapor/src/vdomInterop.ts | 36 +++++++------ 3 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 packages/runtime-vapor/__tests__/vdomInterop.spec.ts diff --git a/packages/runtime-vapor/__tests__/_utils.ts b/packages/runtime-vapor/__tests__/_utils.ts index 0ed6455447..f794d409f2 100644 --- a/packages/runtime-vapor/__tests__/_utils.ts +++ b/packages/runtime-vapor/__tests__/_utils.ts @@ -1,7 +1,8 @@ -import { createVaporApp } from '../src' +import { createVaporApp, vaporInteropPlugin } from '../src' import type { App } from '@vue/runtime-dom' import type { VaporComponent, VaporComponentInstance } from '../src/component' import type { RawProps } from '../src/componentProps' +import { type Component, createApp } from 'vue' export interface RenderContext { component: VaporComponent @@ -82,3 +83,54 @@ export function makeRender( return define } + +export interface InteropRenderContext { + mount: (container?: string | ParentNode) => InteropRenderContext + render: ( + props?: RawProps, + container?: string | ParentNode, + ) => InteropRenderContext + html: () => string +} + +export function makeInteropRender(): (comp: Component) => InteropRenderContext { + let host: HTMLElement + beforeEach(() => { + host = document.createElement('div') + }) + afterEach(() => { + host.remove() + }) + + function define(comp: Component) { + let app: App + function render( + props: RawProps | undefined = undefined, + container: string | ParentNode = host, + ) { + app?.unmount() + app = createApp(comp, props) + app.use(vaporInteropPlugin) + return mount(container) + } + + function mount(container: string | ParentNode = host) { + app.mount(container) + return res() + } + + function html() { + return host.innerHTML + } + + const res = () => ({ + mount, + render, + html, + }) + + return res() + } + + return define +} diff --git a/packages/runtime-vapor/__tests__/vdomInterop.spec.ts b/packages/runtime-vapor/__tests__/vdomInterop.spec.ts new file mode 100644 index 0000000000..44bbf009ed --- /dev/null +++ b/packages/runtime-vapor/__tests__/vdomInterop.spec.ts @@ -0,0 +1,29 @@ +import { h } from 'vue' +import { createSlot, defineVaporComponent, template } from '../src' +import { makeInteropRender } from './_utils' + +const define = makeInteropRender() + +describe('vdomInterop', () => { + describe('slots', () => { + test('should render slot fallback if no slot content is provided', () => { + const VaporChild = defineVaporComponent({ + setup() { + const n0 = createSlot('default', null, () => { + const n2 = template('
hi
')() + return n2 + }) + return n0 + }, + }) + + const { html } = define({ + setup() { + return () => h(VaporChild as any) + }, + }).render() + + expect(html()).toBe('
hi
') + }) + }) +}) diff --git a/packages/runtime-vapor/src/vdomInterop.ts b/packages/runtime-vapor/src/vdomInterop.ts index e277024d73..bcae37b6c8 100644 --- a/packages/runtime-vapor/src/vdomInterop.ts +++ b/packages/runtime-vapor/src/vdomInterop.ts @@ -236,24 +236,26 @@ function renderVDOMSlot( frag.insert = (parentNode, anchor) => { if (!isMounted) { renderEffect(() => { - const vnode = renderSlot( - slotsRef.value, - isFunction(name) ? name() : name, - props, - ) - if ((vnode.children as any[]).length) { - if (fallbackNodes) { - remove(fallbackNodes, parentNode) - fallbackNodes = undefined - } - internals.p( - oldVNode, - vnode, - parentNode, - anchor, - parentComponent as any, + if (slotsRef.value) { + const vnode = renderSlot( + slotsRef.value, + isFunction(name) ? name() : name, + props, ) - oldVNode = vnode + if ((vnode.children as any[]).length) { + if (fallbackNodes) { + remove(fallbackNodes, parentNode) + fallbackNodes = undefined + } + internals.p( + oldVNode, + vnode, + parentNode, + anchor, + parentComponent as any, + ) + oldVNode = vnode + } } else { if (fallback && !fallbackNodes) { // mount fallback -- 2.39.5