mirror of https://github.com/vuejs/core.git
fix(suspense/hydration): fix hydration timing of async component inside suspense
close #6638
This commit is contained in:
parent
e255c31c88
commit
1b8e197a5b
|
@ -688,6 +688,54 @@ describe('SSR hydration', () => {
|
|||
expect(container.innerHTML).toBe(`<span>1</span>`)
|
||||
})
|
||||
|
||||
// #6638
|
||||
test('Suspense + async component', async () => {
|
||||
let isSuspenseResolved = false
|
||||
let isSuspenseResolvedInChild: any
|
||||
const AsyncChild = defineAsyncComponent(() =>
|
||||
Promise.resolve(
|
||||
defineComponent({
|
||||
setup() {
|
||||
isSuspenseResolvedInChild = isSuspenseResolved
|
||||
const count = ref(0)
|
||||
return () =>
|
||||
h(
|
||||
'span',
|
||||
{
|
||||
onClick: () => {
|
||||
count.value++
|
||||
},
|
||||
},
|
||||
count.value,
|
||||
)
|
||||
},
|
||||
}),
|
||||
),
|
||||
)
|
||||
const { vnode, container } = mountWithHydration('<span>0</span>', () =>
|
||||
h(
|
||||
Suspense,
|
||||
{
|
||||
onResolve() {
|
||||
isSuspenseResolved = true
|
||||
},
|
||||
},
|
||||
() => h(AsyncChild),
|
||||
),
|
||||
)
|
||||
expect(vnode.el).toBe(container.firstChild)
|
||||
// wait for hydration to finish
|
||||
await new Promise(r => setTimeout(r))
|
||||
|
||||
expect(isSuspenseResolvedInChild).toBe(false)
|
||||
expect(isSuspenseResolved).toBe(true)
|
||||
|
||||
// assert interaction
|
||||
triggerEvent('click', container.querySelector('span')!)
|
||||
await nextTick()
|
||||
expect(container.innerHTML).toBe(`<span>1</span>`)
|
||||
})
|
||||
|
||||
test('Suspense (full integration)', async () => {
|
||||
const mountedCalls: number[] = []
|
||||
const asyncDeps: Promise<any>[] = []
|
||||
|
|
|
@ -1276,7 +1276,7 @@ function baseCreateRenderer(
|
|||
const componentUpdateFn = () => {
|
||||
if (!instance.isMounted) {
|
||||
let vnodeHook: VNodeHook | null | undefined
|
||||
const { el, props } = initialVNode
|
||||
const { el, props, type } = initialVNode
|
||||
const { bm, m, parent } = instance
|
||||
const isAsyncWrapperVNode = isAsyncWrapper(initialVNode)
|
||||
|
||||
|
@ -1325,8 +1325,11 @@ function baseCreateRenderer(
|
|||
}
|
||||
}
|
||||
|
||||
if (isAsyncWrapperVNode) {
|
||||
;(initialVNode.type as ComponentOptions).__asyncLoader!().then(
|
||||
if (
|
||||
isAsyncWrapperVNode &&
|
||||
!(type as ComponentOptions).__asyncResolved
|
||||
) {
|
||||
;(type as ComponentOptions).__asyncLoader!().then(
|
||||
// note: we are moving the render call into an async callback,
|
||||
// which means it won't track dependencies - but it's ok because
|
||||
// a server-rendered async wrapper is already in resolved state
|
||||
|
|
Loading…
Reference in New Issue