fix(custom-element): update slot nodes when shadowRoot is false

This commit is contained in:
daiwei 2025-04-16 11:34:33 +08:00
parent 4f792535e2
commit 8e5a43842b
4 changed files with 40 additions and 0 deletions

View File

@ -96,6 +96,7 @@ export function renderSlot(
if (slot && (slot as ContextualRenderFn)._c) { if (slot && (slot as ContextualRenderFn)._c) {
;(slot as ContextualRenderFn)._d = true ;(slot as ContextualRenderFn)._d = true
} }
rendered.slotName = name
return rendered return rendered
} }

View File

@ -934,6 +934,10 @@ function baseCreateRenderer(
dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated') dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated')
}, parentSuspense) }, parentSuspense)
} }
if (el._isVueCE && !el._def.shadowRoot) {
el._updateSlots(n2.children)
}
} }
// The fast path for blocks. // The fast path for blocks.

View File

@ -253,6 +253,10 @@ export interface VNode<
* @internal custom element interception hook * @internal custom element interception hook
*/ */
ce?: (instance: ComponentInternalInstance) => void ce?: (instance: ComponentInternalInstance) => void
/**
* @internal
*/
slotName?: string
} }
// Since v-if and v-for are the two possible ways node structure can dynamically // Since v-if and v-for are the two possible ways node structure can dynamically
@ -715,6 +719,7 @@ export function cloneVNode<T, U>(
anchor: vnode.anchor, anchor: vnode.anchor,
ctx: vnode.ctx, ctx: vnode.ctx,
ce: vnode.ce, ce: vnode.ce,
slotName: vnode.slotName,
} }
// if the vnode will be replaced by the cloned one, it is necessary // if the vnode will be replaced by the cloned one, it is necessary

View File

@ -19,15 +19,18 @@ import {
type EmitsOptions, type EmitsOptions,
type EmitsToProps, type EmitsToProps,
type ExtractPropTypes, type ExtractPropTypes,
Fragment,
type MethodOptions, type MethodOptions,
type RenderFunction, type RenderFunction,
type SetupContext, type SetupContext,
type SlotsType, type SlotsType,
type VNode, type VNode,
type VNodeArrayChildren,
type VNodeProps, type VNodeProps,
createVNode, createVNode,
defineComponent, defineComponent,
getCurrentInstance, getCurrentInstance,
isVNode,
nextTick, nextTick,
unref, unref,
warn, 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 * @internal
*/ */
@ -710,3 +724,19 @@ export function useShadowRoot(): ShadowRoot | null {
const el = __DEV__ ? useHost('useShadowRoot') : useHost() const el = __DEV__ ? useHost('useShadowRoot') : useHost()
return el && el.shadowRoot 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
}