Skip to content

Commit 1a5ea55

Browse files
committed
test: add tests
1 parent 68b2001 commit 1a5ea55

File tree

2 files changed

+110
-11
lines changed

2 files changed

+110
-11
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,25 @@ import {
55
Teleport,
66
type VueElement,
77
createApp,
8+
createBlock,
9+
createCommentVNode,
10+
createElementBlock,
11+
createElementVNode,
812
defineAsyncComponent,
913
defineComponent,
1014
defineCustomElement,
1115
h,
1216
inject,
1317
nextTick,
1418
onMounted,
19+
openBlock,
1520
provide,
1621
ref,
1722
render,
1823
renderSlot,
1924
useHost,
2025
useShadowRoot,
26+
withCtx,
2127
} from '../src'
2228

2329
declare var __VUE_HMR_RUNTIME__: HMRRuntime
@@ -1131,6 +1137,92 @@ describe('defineCustomElement', () => {
11311137
expect(target.innerHTML).toBe(`<span>default</span>`)
11321138
app.unmount()
11331139
})
1140+
1141+
//#13206
1142+
test('should update slotted children correctly w/ shadowRoot false', async () => {
1143+
const E = defineCustomElement(
1144+
defineComponent({
1145+
props: {
1146+
isShown: { type: Boolean, required: true },
1147+
},
1148+
render() {
1149+
return this.isShown
1150+
? h('div', { key: 0 }, [renderSlot(this.$slots, 'default')])
1151+
: null
1152+
},
1153+
}),
1154+
{ shadowRoot: false },
1155+
)
1156+
customElements.define('ce-shadow-root-false', E)
1157+
1158+
const Comp = defineComponent({
1159+
props: {
1160+
isShown: { type: Boolean, required: true },
1161+
},
1162+
render() {
1163+
return h('ce-shadow-root-false', { 'is-shown': this.isShown }, [
1164+
renderSlot(this.$slots, 'default'),
1165+
])
1166+
},
1167+
})
1168+
1169+
const isShown = ref(false)
1170+
const count = ref(0)
1171+
1172+
function click() {
1173+
isShown.value = !isShown.value
1174+
count.value++
1175+
}
1176+
1177+
const App = {
1178+
render() {
1179+
return (
1180+
openBlock(),
1181+
createBlock(
1182+
Comp,
1183+
{ isShown: isShown.value },
1184+
{
1185+
default: withCtx(() => [
1186+
createElementVNode('div', null, isShown.value, 1 /* TEXT */),
1187+
count.value > 1
1188+
? (openBlock(), createElementBlock('div', { key: 0 }, 'hi'))
1189+
: createCommentVNode('v-if', true),
1190+
]),
1191+
_: 1 /* STABLE */,
1192+
},
1193+
8 /* PROPS */,
1194+
['isShown'],
1195+
)
1196+
)
1197+
},
1198+
}
1199+
const container = document.createElement('div')
1200+
document.body.appendChild(container)
1201+
1202+
const app = createApp(App)
1203+
app.mount(container)
1204+
expect(container.innerHTML).toBe(
1205+
`<ce-shadow-root-false data-v-app=""><!----></ce-shadow-root-false>`,
1206+
)
1207+
1208+
click()
1209+
await nextTick()
1210+
expect(container.innerHTML).toBe(
1211+
`<ce-shadow-root-false data-v-app="" is-shown=""><div><div>true</div><!--v-if--></div></ce-shadow-root-false>`,
1212+
)
1213+
1214+
click()
1215+
await nextTick()
1216+
expect(container.innerHTML).toBe(
1217+
`<ce-shadow-root-false data-v-app=""><!----></ce-shadow-root-false>`,
1218+
)
1219+
1220+
click()
1221+
await nextTick()
1222+
expect(container.innerHTML).toBe(
1223+
`<ce-shadow-root-false data-v-app="" is-shown=""><div><div>true</div><div>hi</div></div></ce-shadow-root-false>`,
1224+
)
1225+
})
11341226
})
11351227

11361228
describe('helpers', () => {

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -665,9 +665,8 @@ export class VueElement
665665
*/
666666
_updateSlots(children: VNode[]): void {
667667
children.forEach(child => {
668-
this._slots![child.slotName!] = collectElements(
669-
child.children as VNodeArrayChildren,
670-
)
668+
// slot children are always Fragments
669+
this._slots![child.slotName!] = collectFragmentElements(child)
671670
})
672671
}
673672

@@ -725,16 +724,24 @@ export function useShadowRoot(): ShadowRoot | null {
725724
return el && el.shadowRoot
726725
}
727726

727+
function collectFragmentElements(child: VNode): Node[] {
728+
return [
729+
child.el as Node,
730+
...collectElements(child.children as VNodeArrayChildren),
731+
child.anchor as Node,
732+
]
733+
}
734+
728735
function collectElements(children: VNodeArrayChildren): Node[] {
729736
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)
737+
for (const child of children) {
738+
if (isArray(child)) {
739+
nodes.push(...collectElements(child))
740+
} else if (isVNode(child)) {
741+
if (child.type === Fragment) {
742+
nodes.push(...collectFragmentElements(child))
743+
} else if (child.el) {
744+
nodes.push(child.el as Node)
738745
}
739746
}
740747
}

0 commit comments

Comments
 (0)