diff --git a/packages/reactivity/__tests__/watch.spec.ts b/packages/reactivity/__tests__/watch.spec.ts index b3d18e19f71..cb546c12d15 100644 --- a/packages/reactivity/__tests__/watch.spec.ts +++ b/packages/reactivity/__tests__/watch.spec.ts @@ -5,6 +5,7 @@ import { type WatchOptions, type WatchScheduler, onWatcherCleanup, + reactive, ref, watch, } from '../src' @@ -209,4 +210,16 @@ describe('watch', () => { source.value++ expect(dummy).toBe(1) }) + + test('watch callback should not be called when functional source and deep(true)', async () => { + const spy = vi.fn() + const obj = reactive({ data: { number: 1 } }) + watch( + () => obj.data.number, + val => spy(), + { deep: true }, + ) + obj.data = { number: 1 } + expect(spy).toHaveBeenCalledTimes(0) + }) }) diff --git a/packages/reactivity/src/watch.ts b/packages/reactivity/src/watch.ts index 073bf88b93f..2c6fc9bd439 100644 --- a/packages/reactivity/src/watch.ts +++ b/packages/reactivity/src/watch.ts @@ -241,11 +241,15 @@ export function watch( // watch(source, cb) const newValue = effect.run() if ( - deep || forceTrigger || (isMultiSource - ? (newValue as any[]).some((v, i) => hasChanged(v, oldValue[i])) - : hasChanged(newValue, oldValue)) + ? (newValue as any[]).some( + (v, i) => + (deep && typeof v === 'object') || + hasChanged(v, (oldValue as any[])[i]), + ) + : (deep && typeof newValue === 'object') || + hasChanged(newValue, oldValue)) ) { // cleanup before running cb again if (cleanup) {