feat(runtime-dom): support async component in defineCustomElement
close #4261
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
defineAsyncComponent,
|
||||
defineCustomElement,
|
||||
h,
|
||||
inject,
|
||||
@@ -300,4 +301,96 @@ describe('defineCustomElement', () => {
|
||||
expect(style.textContent).toBe(`div { color: red; }`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('async', () => {
|
||||
test('should work', async () => {
|
||||
const loaderSpy = jest.fn()
|
||||
const E = defineCustomElement(
|
||||
defineAsyncComponent(() => {
|
||||
loaderSpy()
|
||||
return Promise.resolve({
|
||||
props: ['msg'],
|
||||
styles: [`div { color: red }`],
|
||||
render(this: any) {
|
||||
return h('div', null, this.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
customElements.define('my-el-async', E)
|
||||
container.innerHTML =
|
||||
`<my-el-async msg="hello"></my-el-async>` +
|
||||
`<my-el-async msg="world"></my-el-async>`
|
||||
|
||||
await new Promise(r => setTimeout(r))
|
||||
|
||||
// loader should be called only once
|
||||
expect(loaderSpy).toHaveBeenCalledTimes(1)
|
||||
|
||||
const e1 = container.childNodes[0] as VueElement
|
||||
const e2 = container.childNodes[1] as VueElement
|
||||
|
||||
// should inject styles
|
||||
expect(e1.shadowRoot!.innerHTML).toBe(
|
||||
`<div>hello</div><style>div { color: red }</style>`
|
||||
)
|
||||
expect(e2.shadowRoot!.innerHTML).toBe(
|
||||
`<div>world</div><style>div { color: red }</style>`
|
||||
)
|
||||
|
||||
// attr
|
||||
e1.setAttribute('msg', 'attr')
|
||||
await nextTick()
|
||||
expect((e1 as any).msg).toBe('attr')
|
||||
expect(e1.shadowRoot!.innerHTML).toBe(
|
||||
`<div>attr</div><style>div { color: red }</style>`
|
||||
)
|
||||
|
||||
// props
|
||||
expect(`msg` in e1).toBe(true)
|
||||
;(e1 as any).msg = 'prop'
|
||||
expect(e1.getAttribute('msg')).toBe('prop')
|
||||
expect(e1.shadowRoot!.innerHTML).toBe(
|
||||
`<div>prop</div><style>div { color: red }</style>`
|
||||
)
|
||||
})
|
||||
|
||||
test('set DOM property before resolve', async () => {
|
||||
const E = defineCustomElement(
|
||||
defineAsyncComponent(() => {
|
||||
return Promise.resolve({
|
||||
props: ['msg'],
|
||||
render(this: any) {
|
||||
return h('div', this.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
customElements.define('my-el-async-2', E)
|
||||
|
||||
const e1 = new E()
|
||||
|
||||
// set property before connect
|
||||
e1.msg = 'hello'
|
||||
|
||||
const e2 = new E()
|
||||
|
||||
container.appendChild(e1)
|
||||
container.appendChild(e2)
|
||||
|
||||
// set property after connect but before resolve
|
||||
e2.msg = 'world'
|
||||
|
||||
await new Promise(r => setTimeout(r))
|
||||
|
||||
expect(e1.shadowRoot!.innerHTML).toBe(`<div>hello</div>`)
|
||||
expect(e2.shadowRoot!.innerHTML).toBe(`<div>world</div>`)
|
||||
|
||||
e1.msg = 'world'
|
||||
expect(e1.shadowRoot!.innerHTML).toBe(`<div>world</div>`)
|
||||
|
||||
e2.msg = 'hello'
|
||||
expect(e2.shadowRoot!.innerHTML).toBe(`<div>hello</div>`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user