@@ -23,7 +23,8 @@ import {
23
23
onMounted ,
24
24
reactive ,
25
25
shallowRef ,
26
- onDeactivated
26
+ onDeactivated ,
27
+ watch
27
28
} from '@vue/runtime-test'
28
29
import { KeepAliveProps } from '../../src/components/KeepAlive'
29
30
@@ -977,4 +978,72 @@ describe('KeepAlive', () => {
977
978
expect ( mountedB ) . toHaveBeenCalledTimes ( 1 )
978
979
expect ( unmountedB ) . toHaveBeenCalledTimes ( 0 )
979
980
} )
981
+
982
+ test ( 'should pause/resume effectScope in onActivated/onDeactivated' , async ( ) => {
983
+ const renderA = vi . fn ( ( ) => 'A' )
984
+ const renderB = vi . fn ( ( ) => 'B' )
985
+ const msg = ref ( 'hello' )
986
+ const watchSpy = vi . fn ( )
987
+ const A = {
988
+ name : 'A' ,
989
+ setup ( ) {
990
+ watch (
991
+ msg ,
992
+ ( ) => {
993
+ watchSpy ( )
994
+ } ,
995
+ { immediate : true }
996
+ )
997
+ return ( ) => h ( 'div' , [ renderA ( ) , msg . value ] )
998
+ }
999
+ }
1000
+ const B = {
1001
+ name : 'B' ,
1002
+ setup ( ) {
1003
+ return renderB
1004
+ }
1005
+ }
1006
+
1007
+ const current = shallowRef ( A )
1008
+ const app = createApp ( {
1009
+ setup ( ) {
1010
+ return ( ) => {
1011
+ return [ h ( KeepAlive , { } , h ( current . value ) ) ]
1012
+ }
1013
+ }
1014
+ } )
1015
+
1016
+ app . mount ( root )
1017
+
1018
+ expect ( renderA ) . toHaveBeenCalledTimes ( 1 )
1019
+ expect ( watchSpy ) . toHaveBeenCalledTimes ( 1 )
1020
+
1021
+ msg . value = 'world'
1022
+ await nextTick ( )
1023
+ expect ( renderA ) . toHaveBeenCalledTimes ( 2 )
1024
+ expect ( watchSpy ) . toHaveBeenCalledTimes ( 2 )
1025
+
1026
+ // @ts -expect-error
1027
+ current . value = B
1028
+ await nextTick ( )
1029
+ msg . value = 'foo'
1030
+ await nextTick ( )
1031
+
1032
+ // The effect should not be executed after deactivated.
1033
+ expect ( renderA ) . toHaveBeenCalledTimes ( 2 )
1034
+ expect ( watchSpy ) . toHaveBeenCalledTimes ( 2 )
1035
+ current . value = A
1036
+ await nextTick ( )
1037
+
1038
+ // Resume effect execution after activated.
1039
+ // The effect in the render function will be executed immediately after recovery.
1040
+ expect ( renderA ) . toHaveBeenCalledTimes ( 3 )
1041
+ expect ( watchSpy ) . toHaveBeenCalledTimes ( 2 )
1042
+
1043
+ msg . value = 'bar'
1044
+ await nextTick ( )
1045
+
1046
+ expect ( renderA ) . toHaveBeenCalledTimes ( 4 )
1047
+ expect ( watchSpy ) . toHaveBeenCalledTimes ( 3 )
1048
+ } )
980
1049
} )
0 commit comments