diff --git a/packages/runtime-core/src/helpers/renderSlot.ts b/packages/runtime-core/src/helpers/renderSlot.ts index 9389cc28abe..9310ee0b8f4 100644 --- a/packages/runtime-core/src/helpers/renderSlot.ts +++ b/packages/runtime-core/src/helpers/renderSlot.ts @@ -4,8 +4,9 @@ import { ContextualRenderFn, currentRenderingInstance } from '../componentRenderContext' -import { Comment, isVNode } from '../vnode' import { + Comment, + isVNode, VNodeArrayChildren, openBlock, createBlock, @@ -15,6 +16,7 @@ import { import { PatchFlags, SlotFlags } from '@vue/shared' import { warn } from '../warning' import { createVNode } from '@vue/runtime-core' +import { isAsyncWrapper } from '../apiAsyncComponent' /** * Compiler runtime helper for rendering `` @@ -29,7 +31,12 @@ export function renderSlot( fallback?: () => VNodeArrayChildren, noSlotted?: boolean ): VNode { - if (currentRenderingInstance!.isCE) { + if ( + currentRenderingInstance!.isCE || + (currentRenderingInstance!.parent && + isAsyncWrapper(currentRenderingInstance!.parent) && + currentRenderingInstance!.parent.isCE) + ) { return createVNode( 'slot', name === 'default' ? null : { name }, diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index 7e69ec28ef2..22b4d91d0bd 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -426,5 +426,33 @@ describe('defineCustomElement', () => { const e = container.childNodes[0] as VueElement expect(e.shadowRoot!.innerHTML).toBe(`
20,number
`) }) + + test('with slots', async () => { + const E = defineCustomElement( + defineAsyncComponent(() => { + return Promise.resolve({ + render(this: any) { + return [ + h('div', null, [ + renderSlot(this.$slots, 'default', undefined, () => [ + h('div', 'fallback') + ]) + ]), + h('div', null, renderSlot(this.$slots, 'named')) + ] + } + }) + }) + ) + customElements.define('my-el-async-slots', E) + container.innerHTML = `hi` + + await new Promise(r => setTimeout(r)) + + const e = container.childNodes[0] as VueElement + expect(e.shadowRoot!.innerHTML).toBe( + `
fallback
` + ) + }) }) })