From: daiwei Date: Wed, 16 Apr 2025 03:34:33 +0000 (+0800) Subject: fix(custom-element): update slot nodes when shadowRoot is false X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e5a43842b5dc068860a42e867094ec65bed9bff;p=thirdparty%2Fvuejs%2Fcore.git fix(custom-element): update slot nodes when shadowRoot is false --- diff --git a/packages/runtime-core/src/helpers/renderSlot.ts b/packages/runtime-core/src/helpers/renderSlot.ts index 92f7dab36b..aec49d1eae 100644 --- a/packages/runtime-core/src/helpers/renderSlot.ts +++ b/packages/runtime-core/src/helpers/renderSlot.ts @@ -96,6 +96,7 @@ export function renderSlot( if (slot && (slot as ContextualRenderFn)._c) { ;(slot as ContextualRenderFn)._d = true } + rendered.slotName = name return rendered } diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 05c4ac345e..9494dac09d 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -934,6 +934,10 @@ function baseCreateRenderer( dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated') }, parentSuspense) } + + if (el._isVueCE && !el._def.shadowRoot) { + el._updateSlots(n2.children) + } } // The fast path for blocks. diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index a8c5340cd1..a146cdc162 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -253,6 +253,10 @@ export interface VNode< * @internal custom element interception hook */ ce?: (instance: ComponentInternalInstance) => void + /** + * @internal + */ + slotName?: string } // Since v-if and v-for are the two possible ways node structure can dynamically @@ -715,6 +719,7 @@ export function cloneVNode( anchor: vnode.anchor, ctx: vnode.ctx, ce: vnode.ce, + slotName: vnode.slotName, } // if the vnode will be replaced by the cloned one, it is necessary diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index aeeaeec9b9..5cab16ad67 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -19,15 +19,18 @@ import { type EmitsOptions, type EmitsToProps, type ExtractPropTypes, + Fragment, type MethodOptions, type RenderFunction, type SetupContext, type SlotsType, type VNode, + type VNodeArrayChildren, type VNodeProps, createVNode, defineComponent, getCurrentInstance, + isVNode, nextTick, unref, warn, @@ -657,6 +660,17 @@ export class VueElement } } + /** + * @internal + */ + _updateSlots(children: VNode[]): void { + children.forEach(child => { + this._slots![child.slotName!] = collectElements( + child.children as VNodeArrayChildren, + ) + }) + } + /** * @internal */ @@ -710,3 +724,19 @@ export function useShadowRoot(): ShadowRoot | null { const el = __DEV__ ? useHost('useShadowRoot') : useHost() return el && el.shadowRoot } + +function collectElements(children: VNodeArrayChildren): Node[] { + const nodes: Node[] = [] + for (const vnode of children) { + if (isArray(vnode)) { + nodes.push(...collectElements(vnode)) + } else if (isVNode(vnode)) { + if (vnode.type === Fragment) { + nodes.push(...collectElements(vnode.children as VNodeArrayChildren)) + } else if (vnode.el) { + nodes.push(vnode.el as Node) + } + } + } + return nodes +}