KeepAlive,
Suspense,
type SuspenseProps,
+ createBlock,
createCommentVNode,
+ createElementBlock,
h,
nextTick,
nodeOps,
onErrorCaptured,
onMounted,
onUnmounted,
+ openBlock,
ref,
render,
resolveDynamicComponent,
import { computed, createApp, defineComponent, inject, provide } from 'vue'
import type { RawSlots } from 'packages/runtime-core/src/componentSlots'
import { resetSuspenseId } from '../../src/components/Suspense'
+import { PatchFlags } from '@vue/shared'
describe('Suspense', () => {
const deps: Promise<any>[] = []
await Promise.all(deps)
})
+ // #12920
+ test('unmount Suspense after children self-update', async () => {
+ const Comp = defineAsyncComponent({
+ setup() {
+ const show = ref(true)
+ onMounted(() => {
+ // trigger self-update
+ show.value = !show.value
+ })
+ return () =>
+ show.value
+ ? (openBlock(), createElementBlock('div', { key: 0 }, 'show'))
+ : (openBlock(), createElementBlock('div', { key: 1 }, 'hidden'))
+ },
+ })
+
+ const toggle = ref(true)
+ const root = nodeOps.createElement('div')
+ const App = {
+ render() {
+ return (
+ openBlock(),
+ createElementBlock(
+ Fragment,
+ null,
+ [
+ h('h1', null, toggle.value),
+ toggle.value
+ ? (openBlock(),
+ createBlock(
+ Suspense,
+ { key: 0 },
+ {
+ default: h(Comp),
+ },
+ ))
+ : createCommentVNode('v-if', true),
+ ],
+ PatchFlags.STABLE_FRAGMENT,
+ )
+ )
+ },
+ }
+ render(h(App), root)
+ expect(serializeInner(root)).toBe(`<h1>true</h1><!---->`)
+
+ await Promise.all(deps)
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<h1>true</h1><div>hidden</div>`)
+
+ // unmount suspense
+ toggle.value = false
+ await Promise.all(deps)
+ await nextTick()
+ expect(serializeInner(root)).toBe(`<h1>true</h1><!--v-if-->`)
+ })
+
describe('warnings', () => {
// base function to check if a combination of slots warns or not
function baseCheckWarn(
while (parent) {
const root = parent.subTree
if (root.suspense && root.suspense.activeBranch === vnode) {
- root.el = vnode.el
+ root.suspense.vnode.el = root.el = vnode.el
}
if (root === vnode) {
;(vnode = parent.vnode).el = el
- if (suspense && suspense.activeBranch === vnode) suspense.vnode.el = el
parent = parent.parent
} else {
break
}
}
+ // also update suspense vnode el
+ if (suspense && suspense.activeBranch === vnode) {
+ suspense.vnode.el = el
+ }
}