@@ -22,7 +22,8 @@ import {
22
22
SetupContext ,
23
23
createApp ,
24
24
FunctionalComponent ,
25
- renderList
25
+ renderList ,
26
+ onUnmounted
26
27
} from '@vue/runtime-test'
27
28
import { PatchFlags , SlotFlags } from '@vue/shared'
28
29
import { SuspenseImpl } from '../src/components/Suspense'
@@ -826,6 +827,55 @@ describe('renderer: optimized mode', () => {
826
827
expect ( inner ( root ) ) . toBe ( '<div><div>true</div></div>' )
827
828
} )
828
829
830
+ // #4183
831
+ test ( 'should not take unmount children fast path /w Suspense' , async ( ) => {
832
+ const show = ref ( true )
833
+ const spyUnmounted = jest . fn ( )
834
+
835
+ const Parent = {
836
+ setup ( props : any , { slots } : SetupContext ) {
837
+ return ( ) => (
838
+ openBlock ( ) ,
839
+ createBlock ( SuspenseImpl , null , {
840
+ default : withCtx ( ( ) => [ renderSlot ( slots , 'default' ) ] ) ,
841
+ _ : SlotFlags . FORWARDED
842
+ } )
843
+ )
844
+ }
845
+ }
846
+
847
+ const Child = {
848
+ setup ( ) {
849
+ onUnmounted ( spyUnmounted )
850
+ return ( ) => createVNode ( 'div' , null , show . value , PatchFlags . TEXT )
851
+ }
852
+ }
853
+
854
+ const app = createApp ( {
855
+ render ( ) {
856
+ return show . value
857
+ ? ( openBlock ( ) ,
858
+ createBlock (
859
+ Parent ,
860
+ { key : 0 } ,
861
+ {
862
+ default : withCtx ( ( ) => [ createVNode ( Child ) ] ) ,
863
+ _ : SlotFlags . STABLE
864
+ }
865
+ ) )
866
+ : createCommentVNode ( 'v-if' , true )
867
+ }
868
+ } )
869
+
870
+ app . mount ( root )
871
+ expect ( inner ( root ) ) . toBe ( '<div>true</div>' )
872
+
873
+ show . value = false
874
+ await nextTick ( )
875
+ expect ( inner ( root ) ) . toBe ( '<!--v-if-->' )
876
+ expect ( spyUnmounted ) . toHaveBeenCalledTimes ( 1 )
877
+ } )
878
+
829
879
// #3881
830
880
// root cause: fragment inside a compiled slot passed to component which
831
881
// programmatically invokes the slot. The entire slot should de-opt but
0 commit comments