@@ -8,13 +8,16 @@ import {
8
8
KeepAlive ,
9
9
Suspense ,
10
10
type SuspenseProps ,
11
+ createBlock ,
11
12
createCommentVNode ,
13
+ createElementBlock ,
12
14
h ,
13
15
nextTick ,
14
16
nodeOps ,
15
17
onErrorCaptured ,
16
18
onMounted ,
17
19
onUnmounted ,
20
+ openBlock ,
18
21
ref ,
19
22
render ,
20
23
resolveDynamicComponent ,
@@ -26,6 +29,7 @@ import {
26
29
import { computed , createApp , defineComponent , inject , provide } from 'vue'
27
30
import type { RawSlots } from 'packages/runtime-core/src/componentSlots'
28
31
import { resetSuspenseId } from '../../src/components/Suspense'
32
+ import { PatchFlags } from '@vue/shared'
29
33
30
34
describe ( 'Suspense' , ( ) => {
31
35
const deps : Promise < any > [ ] = [ ]
@@ -2161,6 +2165,63 @@ describe('Suspense', () => {
2161
2165
await Promise . all ( deps )
2162
2166
} )
2163
2167
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
+
2164
2225
describe ( 'warnings' , ( ) => {
2165
2226
// base function to check if a combination of slots warns or not
2166
2227
function baseCheckWarn (
0 commit comments