fix(runtime-core/watch): trigger watcher with undefined as initial value (#687)
Fix #683
This commit is contained in:
		
							parent
							
								
									3ddb441c56
								
							
						
					
					
						commit
						5742a0b826
					
				| @ -27,6 +27,33 @@ describe('api: watch', () => { | |||||||
|     expect(dummy).toBe(1) |     expect(dummy).toBe(1) | ||||||
|   }) |   }) | ||||||
| 
 | 
 | ||||||
|  |   it('triggers when initial value is null', async () => { | ||||||
|  |     const state = ref(null) | ||||||
|  |     const spy = jest.fn() | ||||||
|  |     watch(() => state.value, spy) | ||||||
|  |     await nextTick() | ||||||
|  |     expect(spy).toHaveBeenCalled() | ||||||
|  |   }) | ||||||
|  | 
 | ||||||
|  |   it('triggers when initial value is undefined', async () => { | ||||||
|  |     const state = ref() | ||||||
|  |     const spy = jest.fn() | ||||||
|  |     watch(() => state.value, spy) | ||||||
|  |     await nextTick() | ||||||
|  |     expect(spy).toHaveBeenCalled() | ||||||
|  |     state.value = 3 | ||||||
|  |     await nextTick() | ||||||
|  |     expect(spy).toHaveBeenCalledTimes(2) | ||||||
|  |     // testing if undefined can trigger the watcher
 | ||||||
|  |     state.value = undefined | ||||||
|  |     await nextTick() | ||||||
|  |     expect(spy).toHaveBeenCalledTimes(3) | ||||||
|  |     // it shouldn't trigger if the same value is set
 | ||||||
|  |     state.value = undefined | ||||||
|  |     await nextTick() | ||||||
|  |     expect(spy).toHaveBeenCalledTimes(3) | ||||||
|  |   }) | ||||||
|  | 
 | ||||||
|   it('watching single source: getter', async () => { |   it('watching single source: getter', async () => { | ||||||
|     const state = reactive({ count: 0 }) |     const state = reactive({ count: 0 }) | ||||||
|     let dummy |     let dummy | ||||||
|  | |||||||
| @ -61,6 +61,9 @@ export type StopHandle = () => void | |||||||
| 
 | 
 | ||||||
| const invoke = (fn: Function) => fn() | const invoke = (fn: Function) => fn() | ||||||
| 
 | 
 | ||||||
|  | // initial value for watchers to trigger on undefined initial values
 | ||||||
|  | const INITIAL_WATCHER_VALUE = {} | ||||||
|  | 
 | ||||||
| // overload #1: simple effect
 | // overload #1: simple effect
 | ||||||
| export function watch(effect: WatchEffect, options?: WatchOptions): StopHandle | export function watch(effect: WatchEffect, options?: WatchOptions): StopHandle | ||||||
| 
 | 
 | ||||||
| @ -153,7 +156,7 @@ function doWatch( | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   let oldValue = isArray(source) ? [] : undefined |   let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE | ||||||
|   const applyCb = cb |   const applyCb = cb | ||||||
|     ? () => { |     ? () => { | ||||||
|         if (instance && instance.isUnmounted) { |         if (instance && instance.isUnmounted) { | ||||||
| @ -167,7 +170,8 @@ function doWatch( | |||||||
|           } |           } | ||||||
|           callWithAsyncErrorHandling(cb, instance, ErrorCodes.WATCH_CALLBACK, [ |           callWithAsyncErrorHandling(cb, instance, ErrorCodes.WATCH_CALLBACK, [ | ||||||
|             newValue, |             newValue, | ||||||
|             oldValue, |             // pass undefined as the old value when it's changed for the first time
 | ||||||
|  |             oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue, | ||||||
|             registerCleanup |             registerCleanup | ||||||
|           ]) |           ]) | ||||||
|           oldValue = newValue |           oldValue = newValue | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user