Skip to content

Commit 84ca349

Browse files
authored
fix(custom-element): optimize slot retrieval to avoid duplicates (#13961)
close #13955
1 parent 8ca2b3f commit 84ca349

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,44 @@ describe('defineCustomElement', () => {
16141614
app.unmount()
16151615
})
16161616

1617+
test('teleport target is ancestor of custom element host', async () => {
1618+
const Child = defineCustomElement(
1619+
{
1620+
render() {
1621+
return [
1622+
h(Teleport, { to: '#t1' }, [renderSlot(this.$slots, 'header')]),
1623+
]
1624+
},
1625+
},
1626+
{ shadowRoot: false },
1627+
)
1628+
customElements.define('my-el-teleport-child-target', Child)
1629+
1630+
const App = {
1631+
render() {
1632+
return h('div', { id: 't1' }, [
1633+
h('my-el-teleport-child-target', null, {
1634+
default: () => [h('div', { slot: 'header' }, 'header')],
1635+
}),
1636+
])
1637+
},
1638+
}
1639+
const app = createApp(App)
1640+
app.mount(container)
1641+
1642+
const target1 = document.getElementById('t1')!
1643+
expect(target1.outerHTML).toBe(
1644+
`<div id="t1">` +
1645+
`<my-el-teleport-child-target data-v-app="">` +
1646+
`<!--teleport start--><!--teleport end-->` +
1647+
`</my-el-teleport-child-target>` +
1648+
`<div slot="header">header</div>` +
1649+
`</div>`,
1650+
)
1651+
1652+
app.unmount()
1653+
})
1654+
16171655
test('toggle nested custom element with shadowRoot: false', async () => {
16181656
customElements.define(
16191657
'my-el-child-shadow-false',

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,11 +688,18 @@ export class VueElement
688688
if (this._teleportTargets) {
689689
roots.push(...this._teleportTargets)
690690
}
691-
return roots.reduce<HTMLSlotElement[]>((res, i) => {
692-
res.push(...Array.from(i.querySelectorAll('slot')))
693-
return res
694-
}, [])
691+
692+
const slots = new Set<HTMLSlotElement>()
693+
for (const root of roots) {
694+
const found = root.querySelectorAll<HTMLSlotElement>('slot')
695+
for (let i = 0; i < found.length; i++) {
696+
slots.add(found[i])
697+
}
698+
}
699+
700+
return Array.from(slots)
695701
}
702+
696703
/**
697704
* @internal
698705
*/

0 commit comments

Comments
 (0)