From 5358bca4a80cf52d19ed91967eeaa025a786083d Mon Sep 17 00:00:00 2001 From: edison Date: Wed, 24 Sep 2025 17:08:25 +0800 Subject: [PATCH] fix(custom-element): use PatchFlags.BAIL for slot when props are present (#13907) close #13904 --- .../runtime-core/src/helpers/renderSlot.ts | 3 ++- .../__tests__/customElement.spec.ts | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/src/helpers/renderSlot.ts b/packages/runtime-core/src/helpers/renderSlot.ts index 92f7dab36b..2f1296bb13 100644 --- a/packages/runtime-core/src/helpers/renderSlot.ts +++ b/packages/runtime-core/src/helpers/renderSlot.ts @@ -37,6 +37,7 @@ export function renderSlot( isAsyncWrapper(currentRenderingInstance!.parent) && currentRenderingInstance!.parent.ce) ) { + const hasProps = Object.keys(props).length > 0 // in custom element mode, render as actual slot outlets // wrap it with a fragment because in shadowRoot: false mode the slot // element gets replaced by injected content @@ -47,7 +48,7 @@ export function renderSlot( Fragment, null, [createVNode('slot', props, fallback && fallback())], - PatchFlags.STABLE_FRAGMENT, + hasProps ? PatchFlags.BAIL : PatchFlags.STABLE_FRAGMENT, ) ) } diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index cb09cf4d9e..52350dfd27 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -638,6 +638,33 @@ describe('defineCustomElement', () => { `
fallback
`, ) }) + + test('render slot props', async () => { + const foo = ref('foo') + const E = defineCustomElement({ + render() { + return [ + h( + 'div', + null, + renderSlot(this.$slots, 'default', { class: foo.value }), + ), + ] + }, + }) + customElements.define('my-el-slot-props', E) + container.innerHTML = `hi` + const e = container.childNodes[0] as VueElement + expect(e.shadowRoot!.innerHTML).toBe( + `
`, + ) + + foo.value = 'bar' + await nextTick() + expect(e.shadowRoot!.innerHTML).toBe( + `
`, + ) + }) }) describe('provide/inject', () => { -- 2.47.3