@@ -8,13 +8,16 @@ import {
88 KeepAlive ,
99 Suspense ,
1010 type SuspenseProps ,
11+ createBlock ,
1112 createCommentVNode ,
13+ createElementBlock ,
1214 h ,
1315 nextTick ,
1416 nodeOps ,
1517 onErrorCaptured ,
1618 onMounted ,
1719 onUnmounted ,
20+ openBlock ,
1821 ref ,
1922 render ,
2023 resolveDynamicComponent ,
@@ -26,6 +29,7 @@ import {
2629import { computed , createApp , defineComponent , inject , provide } from 'vue'
2730import type { RawSlots } from 'packages/runtime-core/src/componentSlots'
2831import { resetSuspenseId } from '../../src/components/Suspense'
32+ import { PatchFlags } from '@vue/shared'
2933
3034describe ( 'Suspense' , ( ) => {
3135 const deps : Promise < any > [ ] = [ ]
@@ -2161,6 +2165,63 @@ describe('Suspense', () => {
21612165 await Promise . all ( deps )
21622166 } )
21632167
2168+ // #12920
2169+ test ( 'unmount Suspense after children self-update' , async ( ) => {
2170+ const Comp = defineAsyncComponent ( {
2171+ setup ( ) {
2172+ const show = ref ( true )
2173+ onMounted ( ( ) => {
2174+ // trigger self-update
2175+ show . value = ! show . value
2176+ } )
2177+ return ( ) =>
2178+ show . value
2179+ ? ( openBlock ( ) , createElementBlock ( 'div' , { key : 0 } , 'show' ) )
2180+ : ( openBlock ( ) , createElementBlock ( 'div' , { key : 1 } , 'hidden' ) )
2181+ } ,
2182+ } )
2183+
2184+ const toggle = ref ( true )
2185+ const root = nodeOps . createElement ( 'div' )
2186+ const App = {
2187+ render ( ) {
2188+ return (
2189+ openBlock ( ) ,
2190+ createElementBlock (
2191+ Fragment ,
2192+ null ,
2193+ [
2194+ h ( 'h1' , null , toggle . value ) ,
2195+ toggle . value
2196+ ? ( openBlock ( ) ,
2197+ createBlock (
2198+ Suspense ,
2199+ { key : 0 } ,
2200+ {
2201+ default : h ( Comp ) ,
2202+ } ,
2203+ ) )
2204+ : createCommentVNode ( 'v-if' , true ) ,
2205+ ] ,
2206+ PatchFlags . STABLE_FRAGMENT ,
2207+ )
2208+ )
2209+ } ,
2210+ }
2211+ render ( h ( App ) , root )
2212+ expect ( serializeInner ( root ) ) . toBe ( `<h1>true</h1><!---->` )
2213+
2214+ await Promise . all ( deps )
2215+ await nextTick ( )
2216+ expect ( serializeInner ( root ) ) . toBe ( `<h1>true</h1><div>hidden</div>` )
2217+
2218+ // unmount suspense
2219+ toggle . value = false
2220+ await Promise . all ( deps )
2221+ await nextTick ( )
2222+ expect ( serializeInner ( root ) ) . toBe ( `<h1>true</h1><!--v-if-->` )
2223+ } )
2224+
21642225 describe ( 'warnings' , ( ) => {
21652226 // base function to check if a combination of slots warns or not
21662227 function baseCheckWarn (
0 commit comments