fix(runtime-core): should call Suspense fallback unmount hook (#1061)

fix #1059
This commit is contained in:
underfin 2020-05-02 04:20:16 +08:00 committed by GitHub
parent b40fcbc4c6
commit 8b85aaeea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 3 deletions

View File

@ -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 () => {

View File

@ -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