Skip to content

Commit f4d2c9f

Browse files
authoredApr 13, 2022
fix(custom-elements): work with async component + slots (#4657)
close #4639
1 parent 1612971 commit f4d2c9f

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed
 

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import {
44
ContextualRenderFn,
55
currentRenderingInstance
66
} from '../componentRenderContext'
7-
import { Comment, isVNode } from '../vnode'
87
import {
8+
Comment,
9+
isVNode,
910
VNodeArrayChildren,
1011
openBlock,
1112
createBlock,
@@ -15,6 +16,7 @@ import {
1516
import { PatchFlags, SlotFlags } from '@vue/shared'
1617
import { warn } from '../warning'
1718
import { createVNode } from '@vue/runtime-core'
19+
import { isAsyncWrapper } from '../apiAsyncComponent'
1820

1921
/**
2022
* Compiler runtime helper for rendering `<slot/>`
@@ -29,7 +31,12 @@ export function renderSlot(
2931
fallback?: () => VNodeArrayChildren,
3032
noSlotted?: boolean
3133
): VNode {
32-
if (currentRenderingInstance!.isCE) {
34+
if (
35+
currentRenderingInstance!.isCE ||
36+
(currentRenderingInstance!.parent &&
37+
isAsyncWrapper(currentRenderingInstance!.parent) &&
38+
currentRenderingInstance!.parent.isCE)
39+
) {
3340
return createVNode(
3441
'slot',
3542
name === 'default' ? null : { name },

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

+28
Original file line numberDiff line numberDiff line change
@@ -457,5 +457,33 @@ describe('defineCustomElement', () => {
457457
const e = container.childNodes[0] as VueElement
458458
expect(e.shadowRoot!.innerHTML).toBe(`<div>20,number</div>`)
459459
})
460+
461+
test('with slots', async () => {
462+
const E = defineCustomElement(
463+
defineAsyncComponent(() => {
464+
return Promise.resolve({
465+
render(this: any) {
466+
return [
467+
h('div', null, [
468+
renderSlot(this.$slots, 'default', undefined, () => [
469+
h('div', 'fallback')
470+
])
471+
]),
472+
h('div', null, renderSlot(this.$slots, 'named'))
473+
]
474+
}
475+
})
476+
})
477+
)
478+
customElements.define('my-el-async-slots', E)
479+
container.innerHTML = `<my-el-async-slots><span>hi</span></my-el-async-slots>`
480+
481+
await new Promise(r => setTimeout(r))
482+
483+
const e = container.childNodes[0] as VueElement
484+
expect(e.shadowRoot!.innerHTML).toBe(
485+
`<div><slot><div>fallback</div></slot></div><div><slot name="named"></slot></div>`
486+
)
487+
})
460488
})
461489
})

0 commit comments

Comments
 (0)
Please sign in to comment.