fix(custom-elements): work with async component + slots (#4657)
close #4639
This commit is contained in:
parent
1612971471
commit
f4d2c9fc6a
@ -4,8 +4,9 @@ import {
|
|||||||
ContextualRenderFn,
|
ContextualRenderFn,
|
||||||
currentRenderingInstance
|
currentRenderingInstance
|
||||||
} from '../componentRenderContext'
|
} from '../componentRenderContext'
|
||||||
import { Comment, isVNode } from '../vnode'
|
|
||||||
import {
|
import {
|
||||||
|
Comment,
|
||||||
|
isVNode,
|
||||||
VNodeArrayChildren,
|
VNodeArrayChildren,
|
||||||
openBlock,
|
openBlock,
|
||||||
createBlock,
|
createBlock,
|
||||||
@ -15,6 +16,7 @@ import {
|
|||||||
import { PatchFlags, SlotFlags } from '@vue/shared'
|
import { PatchFlags, SlotFlags } from '@vue/shared'
|
||||||
import { warn } from '../warning'
|
import { warn } from '../warning'
|
||||||
import { createVNode } from '@vue/runtime-core'
|
import { createVNode } from '@vue/runtime-core'
|
||||||
|
import { isAsyncWrapper } from '../apiAsyncComponent'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiler runtime helper for rendering `<slot/>`
|
* Compiler runtime helper for rendering `<slot/>`
|
||||||
@ -29,7 +31,12 @@ export function renderSlot(
|
|||||||
fallback?: () => VNodeArrayChildren,
|
fallback?: () => VNodeArrayChildren,
|
||||||
noSlotted?: boolean
|
noSlotted?: boolean
|
||||||
): VNode {
|
): VNode {
|
||||||
if (currentRenderingInstance!.isCE) {
|
if (
|
||||||
|
currentRenderingInstance!.isCE ||
|
||||||
|
(currentRenderingInstance!.parent &&
|
||||||
|
isAsyncWrapper(currentRenderingInstance!.parent) &&
|
||||||
|
currentRenderingInstance!.parent.isCE)
|
||||||
|
) {
|
||||||
return createVNode(
|
return createVNode(
|
||||||
'slot',
|
'slot',
|
||||||
name === 'default' ? null : { name },
|
name === 'default' ? null : { name },
|
||||||
|
@ -457,5 +457,33 @@ describe('defineCustomElement', () => {
|
|||||||
const e = container.childNodes[0] as VueElement
|
const e = container.childNodes[0] as VueElement
|
||||||
expect(e.shadowRoot!.innerHTML).toBe(`<div>20,number</div>`)
|
expect(e.shadowRoot!.innerHTML).toBe(`<div>20,number</div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('with slots', async () => {
|
||||||
|
const E = defineCustomElement(
|
||||||
|
defineAsyncComponent(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
render(this: any) {
|
||||||
|
return [
|
||||||
|
h('div', null, [
|
||||||
|
renderSlot(this.$slots, 'default', undefined, () => [
|
||||||
|
h('div', 'fallback')
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
h('div', null, renderSlot(this.$slots, 'named'))
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
customElements.define('my-el-async-slots', E)
|
||||||
|
container.innerHTML = `<my-el-async-slots><span>hi</span></my-el-async-slots>`
|
||||||
|
|
||||||
|
await new Promise(r => setTimeout(r))
|
||||||
|
|
||||||
|
const e = container.childNodes[0] as VueElement
|
||||||
|
expect(e.shadowRoot!.innerHTML).toBe(
|
||||||
|
`<div><slot><div>fallback</div></slot></div><div><slot name="named"></slot></div>`
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user