fix(runtime-core): should call Suspense fallback unmount hook (#1061)
fix #1059
This commit is contained in:
parent
b40fcbc4c6
commit
8b85aaeea9
@ -221,6 +221,57 @@ describe('Suspense', () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #1059
|
||||||
|
test('mounted/updated hooks & fallback component', async () => {
|
||||||
|
const deps: Promise<any>[] = []
|
||||||
|
const calls: string[] = []
|
||||||
|
const toggle = ref(true)
|
||||||
|
|
||||||
|
const Async = {
|
||||||
|
async setup() {
|
||||||
|
const p = new Promise(r => setTimeout(r, 1))
|
||||||
|
// extra tick needed for Node 12+
|
||||||
|
deps.push(p.then(() => Promise.resolve()))
|
||||||
|
|
||||||
|
await p
|
||||||
|
return () => h('div', 'async')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Fallback = {
|
||||||
|
setup() {
|
||||||
|
onMounted(() => {
|
||||||
|
calls.push('mounted')
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
calls.push('unmounted')
|
||||||
|
})
|
||||||
|
return () => h('div', 'fallback')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
return () =>
|
||||||
|
h(Suspense, null, {
|
||||||
|
default: toggle.value ? h(Async) : null,
|
||||||
|
fallback: h(Fallback)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(Comp), root)
|
||||||
|
expect(serializeInner(root)).toBe(`<div>fallback</div>`)
|
||||||
|
expect(calls).toEqual([`mounted`])
|
||||||
|
|
||||||
|
await Promise.all(deps)
|
||||||
|
await nextTick()
|
||||||
|
expect(serializeInner(root)).toBe(`<div>async</div>`)
|
||||||
|
expect(calls).toEqual([`mounted`, `unmounted`])
|
||||||
|
})
|
||||||
|
|
||||||
test('content update before suspense resolve', async () => {
|
test('content update before suspense resolve', async () => {
|
||||||
const Async = defineAsyncComponent({
|
const Async = defineAsyncComponent({
|
||||||
props: { msg: String },
|
props: { msg: String },
|
||||||
@ -316,7 +367,7 @@ describe('Suspense', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect(serializeInner(root)).toBe(`<!---->`)
|
expect(serializeInner(root)).toBe(`<!---->`)
|
||||||
// should discard effects (except for immediate ones)
|
// should discard effects (except for immediate ones)
|
||||||
expect(calls).toEqual(['immediate effect'])
|
expect(calls).toEqual(['immediate effect', 'watch callback', 'unmounted'])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('unmount suspense after resolve', async () => {
|
test('unmount suspense after resolve', async () => {
|
||||||
|
@ -1856,9 +1856,9 @@ function baseCreateRenderer(
|
|||||||
) {
|
) {
|
||||||
queuePostRenderEffect(da, parentSuspense)
|
queuePostRenderEffect(da, parentSuspense)
|
||||||
}
|
}
|
||||||
queuePostFlushCb(() => {
|
queuePostRenderEffect(() => {
|
||||||
instance.isUnmounted = true
|
instance.isUnmounted = true
|
||||||
})
|
}, parentSuspense)
|
||||||
|
|
||||||
// A component with async dep inside a pending suspense is unmounted before
|
// A component with async dep inside a pending suspense is unmounted before
|
||||||
// its async dep resolves. This should remove the dep from the suspense, and
|
// its async dep resolves. This should remove the dep from the suspense, and
|
||||||
|
Loading…
Reference in New Issue
Block a user