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) {
;(slot as ContextualRenderFn)._d = true
}
rendered.slotName = name
return rendered
}

View File

@ -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.

View File

@ -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<T, U>(
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

View File

@ -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
}