|
|
@@ -40,6 +40,8 @@ import { warn } from './warning'
|
|
|
import { DeprecationTypes } from './compat/compatConfig'
|
|
|
import { checkCompatEnabled, isCompatEnabled } from './compat/compatConfig'
|
|
|
import { ObjectWatchOptionItem } from './componentOptions'
|
|
|
+import { useSSRContext } from '@vue/runtime-core'
|
|
|
+import { SSRContext } from '@vue/server-renderer'
|
|
|
|
|
|
export type WatchEffect = (onCleanup: OnCleanup) => void
|
|
|
|
|
|
@@ -280,7 +282,8 @@ function doWatch(
|
|
|
}
|
|
|
|
|
|
// in SSR there is no need to setup an actual effect, and it should be noop
|
|
|
- // unless it's eager
|
|
|
+ // unless it's eager or sync flush
|
|
|
+ let ssrCleanup: (() => void)[] | undefined
|
|
|
if (__SSR__ && isInSSRComponentSetup) {
|
|
|
// we will also not call the invalidate callback (+ runner is not set up)
|
|
|
onCleanup = NOOP
|
|
|
@@ -293,7 +296,12 @@ function doWatch(
|
|
|
onCleanup
|
|
|
])
|
|
|
}
|
|
|
- return NOOP
|
|
|
+ if (flush === 'sync') {
|
|
|
+ const ctx = useSSRContext() as SSRContext
|
|
|
+ ssrCleanup = ctx.__watcherHandles || (ctx.__watcherHandles = [])
|
|
|
+ } else {
|
|
|
+ return NOOP
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
let oldValue: any = isMultiSource
|
|
|
@@ -378,12 +386,15 @@ function doWatch(
|
|
|
effect.run()
|
|
|
}
|
|
|
|
|
|
- return () => {
|
|
|
+ const unwatch = () => {
|
|
|
effect.stop()
|
|
|
if (instance && instance.scope) {
|
|
|
remove(instance.scope.effects!, effect)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (__SSR__ && ssrCleanup) ssrCleanup.push(unwatch)
|
|
|
+ return unwatch
|
|
|
}
|
|
|
|
|
|
// this.$watch
|