Skip to content

Commit 8e5a438

Browse files
committed
fix(custom-element): update slot nodes when shadowRoot is false
1 parent 4f79253 commit 8e5a438

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

packages/runtime-core/src/helpers/renderSlot.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export function renderSlot(
9696
if (slot && (slot as ContextualRenderFn)._c) {
9797
;(slot as ContextualRenderFn)._d = true
9898
}
99+
rendered.slotName = name
99100
return rendered
100101
}
101102

packages/runtime-core/src/renderer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,10 @@ function baseCreateRenderer(
934934
dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated')
935935
}, parentSuspense)
936936
}
937+
938+
if (el._isVueCE && !el._def.shadowRoot) {
939+
el._updateSlots(n2.children)
940+
}
937941
}
938942

939943
// The fast path for blocks.

packages/runtime-core/src/vnode.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ export interface VNode<
253253
* @internal custom element interception hook
254254
*/
255255
ce?: (instance: ComponentInternalInstance) => void
256+
/**
257+
* @internal
258+
*/
259+
slotName?: string
256260
}
257261

258262
// Since v-if and v-for are the two possible ways node structure can dynamically
@@ -715,6 +719,7 @@ export function cloneVNode<T, U>(
715719
anchor: vnode.anchor,
716720
ctx: vnode.ctx,
717721
ce: vnode.ce,
722+
slotName: vnode.slotName,
718723
}
719724

720725
// if the vnode will be replaced by the cloned one, it is necessary

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@ import {
1919
type EmitsOptions,
2020
type EmitsToProps,
2121
type ExtractPropTypes,
22+
Fragment,
2223
type MethodOptions,
2324
type RenderFunction,
2425
type SetupContext,
2526
type SlotsType,
2627
type VNode,
28+
type VNodeArrayChildren,
2729
type VNodeProps,
2830
createVNode,
2931
defineComponent,
3032
getCurrentInstance,
33+
isVNode,
3134
nextTick,
3235
unref,
3336
warn,
@@ -657,6 +660,17 @@ export class VueElement
657660
}
658661
}
659662

663+
/**
664+
* @internal
665+
*/
666+
_updateSlots(children: VNode[]): void {
667+
children.forEach(child => {
668+
this._slots![child.slotName!] = collectElements(
669+
child.children as VNodeArrayChildren,
670+
)
671+
})
672+
}
673+
660674
/**
661675
* @internal
662676
*/
@@ -710,3 +724,19 @@ export function useShadowRoot(): ShadowRoot | null {
710724
const el = __DEV__ ? useHost('useShadowRoot') : useHost()
711725
return el && el.shadowRoot
712726
}
727+
728+
function collectElements(children: VNodeArrayChildren): Node[] {
729+
const nodes: Node[] = []
730+
for (const vnode of children) {
731+
if (isArray(vnode)) {
732+
nodes.push(...collectElements(vnode))
733+
} else if (isVNode(vnode)) {
734+
if (vnode.type === Fragment) {
735+
nodes.push(...collectElements(vnode.children as VNodeArrayChildren))
736+
} else if (vnode.el) {
737+
nodes.push(vnode.el as Node)
738+
}
739+
}
740+
}
741+
return nodes
742+
}

0 commit comments

Comments
 (0)