@@ -19,7 +19,7 @@ import {
19
19
shallowRef ,
20
20
Fragment
21
21
} from '@vue/runtime-test'
22
- import { createApp } from 'vue'
22
+ import { createApp , defineComponent } from 'vue'
23
23
24
24
describe ( 'Suspense' , ( ) => {
25
25
const deps : Promise < any > [ ] = [ ]
@@ -1335,9 +1335,14 @@ describe('Suspense', () => {
1335
1335
h ( Suspense , null , {
1336
1336
default : [
1337
1337
h ( outerToggle . value ? OuterB : OuterA , null , {
1338
- default : ( ) => h ( Suspense , { suspensible : true } , {
1339
- default : h ( innerToggle . value ? InnerB : InnerA )
1340
- } )
1338
+ default : ( ) =>
1339
+ h (
1340
+ Suspense ,
1341
+ { suspensible : true } ,
1342
+ {
1343
+ default : h ( innerToggle . value ? InnerB : InnerA )
1344
+ }
1345
+ )
1341
1346
} )
1342
1347
] ,
1343
1348
fallback : h ( 'div' , 'fallback outer' )
@@ -1400,4 +1405,122 @@ describe('Suspense', () => {
1400
1405
expect ( serializeInner ( root ) ) . toBe ( expected )
1401
1406
expect ( calls ) . toContain ( 'innerB mounted' )
1402
1407
} )
1408
+
1409
+ // #8206
1410
+ test ( 'nested suspense with suspensible & no async deps' , async ( ) => {
1411
+ const calls : string [ ] = [ ]
1412
+ let expected = ''
1413
+
1414
+ const InnerA = defineComponent ( {
1415
+ setup : ( ) => {
1416
+ calls . push ( 'innerA created' )
1417
+ onMounted ( ( ) => {
1418
+ calls . push ( 'innerA mounted' )
1419
+ } )
1420
+ return ( ) => h ( 'div' , 'innerA' )
1421
+ }
1422
+ } )
1423
+
1424
+ const InnerB = defineComponent ( {
1425
+ setup : ( ) => {
1426
+ calls . push ( 'innerB created' )
1427
+ onMounted ( ( ) => {
1428
+ calls . push ( 'innerB mounted' )
1429
+ } )
1430
+ return ( ) => h ( 'div' , 'innerB' )
1431
+ }
1432
+ } )
1433
+
1434
+ const OuterA = defineComponent ( {
1435
+ setup : ( _ , { slots } : any ) => {
1436
+ calls . push ( 'outerA created' )
1437
+ onMounted ( ( ) => {
1438
+ calls . push ( 'outerA mounted' )
1439
+ } )
1440
+ return ( ) => h ( Fragment , null , [ h ( 'div' , 'outerA' ) , slots . default ?.( ) ] )
1441
+ }
1442
+ } )
1443
+
1444
+ const OuterB = defineComponent ( {
1445
+ setup : ( _ , { slots } : any ) => {
1446
+ calls . push ( 'outerB created' )
1447
+ onMounted ( ( ) => {
1448
+ calls . push ( 'outerB mounted' )
1449
+ } )
1450
+ return ( ) => h ( Fragment , null , [ h ( 'div' , 'outerB' ) , slots . default ?.( ) ] )
1451
+ }
1452
+ } )
1453
+
1454
+ const outerToggle = ref ( false )
1455
+ const innerToggle = ref ( false )
1456
+
1457
+ /**
1458
+ * <Suspense>
1459
+ * <component :is="outerToggle ? outerB : outerA">
1460
+ * <Suspense suspensible>
1461
+ * <component :is="innerToggle ? innerB : innerA" />
1462
+ * </Suspense>
1463
+ * </component>
1464
+ * </Suspense>
1465
+ */
1466
+ const Comp = defineComponent ( {
1467
+ setup ( ) {
1468
+ return ( ) =>
1469
+ h ( Suspense , null , {
1470
+ default : [
1471
+ h ( outerToggle . value ? OuterB : OuterA , null , {
1472
+ default : ( ) =>
1473
+ h (
1474
+ Suspense ,
1475
+ { suspensible : true } ,
1476
+ {
1477
+ default : h ( innerToggle . value ? InnerB : InnerA )
1478
+ }
1479
+ )
1480
+ } )
1481
+ ] ,
1482
+ fallback : h ( 'div' , 'fallback outer' )
1483
+ } )
1484
+ }
1485
+ } )
1486
+
1487
+ expected = `<div>outerA</div><div>innerA</div>`
1488
+ const root = nodeOps . createElement ( 'div' )
1489
+ render ( h ( Comp ) , root )
1490
+ expect ( serializeInner ( root ) ) . toBe ( expected )
1491
+
1492
+ // mount outer component and inner component
1493
+ await Promise . all ( deps )
1494
+ await nextTick ( )
1495
+
1496
+ expect ( serializeInner ( root ) ) . toBe ( expected )
1497
+ expect ( calls ) . toEqual ( [
1498
+ 'outerA created' ,
1499
+ 'innerA created' ,
1500
+ 'innerA mounted' ,
1501
+ 'outerA mounted'
1502
+ ] )
1503
+
1504
+ // toggle outer component
1505
+ calls . length = 0
1506
+ deps . length = 0
1507
+ outerToggle . value = true
1508
+ await nextTick ( )
1509
+
1510
+ await Promise . all ( deps )
1511
+ await nextTick ( )
1512
+ expected = `<div>outerB</div><div>innerA</div>`
1513
+ expect ( serializeInner ( root ) ) . toBe ( expected )
1514
+ expect ( calls ) . toContain ( 'outerB mounted' )
1515
+ expect ( calls ) . toContain ( 'innerA mounted' )
1516
+
1517
+ // toggle inner component
1518
+ calls . length = 0
1519
+ deps . length = 0
1520
+ innerToggle . value = true
1521
+ await Promise . all ( deps )
1522
+ await nextTick ( )
1523
+ expected = `<div>outerB</div><div>innerB</div>`
1524
+ expect ( serializeInner ( root ) ) . toBe ( expected )
1525
+ } )
1403
1526
} )
0 commit comments