@@ -40,6 +40,8 @@ import { warn } from './warning'
40
40
import { DeprecationTypes } from './compat/compatConfig'
41
41
import { checkCompatEnabled , isCompatEnabled } from './compat/compatConfig'
42
42
import { ObjectWatchOptionItem } from './componentOptions'
43
+ import { useSSRContext } from '@vue/runtime-core'
44
+ import { SSRContext } from '@vue/server-renderer'
43
45
44
46
export type WatchEffect = ( onCleanup : OnCleanup ) => void
45
47
@@ -280,7 +282,8 @@ function doWatch(
280
282
}
281
283
282
284
// in SSR there is no need to setup an actual effect, and it should be noop
283
- // unless it's eager
285
+ // unless it's eager or sync flush
286
+ let ssrCleanup : ( ( ) => void ) [ ] | undefined
284
287
if ( __SSR__ && isInSSRComponentSetup ) {
285
288
// we will also not call the invalidate callback (+ runner is not set up)
286
289
onCleanup = NOOP
@@ -293,7 +296,12 @@ function doWatch(
293
296
onCleanup
294
297
] )
295
298
}
296
- return NOOP
299
+ if ( flush === 'sync' ) {
300
+ const ctx = useSSRContext ( ) as SSRContext
301
+ ssrCleanup = ctx . __watcherHandles || ( ctx . __watcherHandles = [ ] )
302
+ } else {
303
+ return NOOP
304
+ }
297
305
}
298
306
299
307
let oldValue : any = isMultiSource
@@ -378,12 +386,15 @@ function doWatch(
378
386
effect . run ( )
379
387
}
380
388
381
- return ( ) => {
389
+ const unwatch = ( ) => {
382
390
effect . stop ( )
383
391
if ( instance && instance . scope ) {
384
392
remove ( instance . scope . effects ! , effect )
385
393
}
386
394
}
395
+
396
+ if ( __SSR__ && ssrCleanup ) ssrCleanup . push ( unwatch )
397
+ return unwatch
387
398
}
388
399
389
400
// this.$watch
0 commit comments