@@ -7,18 +7,15 @@ import {
77 isArray ,
88 isFunction ,
99 emptyObject ,
10- remove ,
1110 hasChanged ,
1211 isServerRendering ,
1312 invokeWithErrorHandling
1413} from 'core/util'
1514import { currentInstance } from './currentInstance'
1615import { traverse } from 'core/observer/traverse'
17- import {
18- EffectScheduler ,
19- ReactiveEffect ,
20- DebuggerEvent
21- } from './reactivity/effect'
16+ import Watcher from '../core/observer/watcher'
17+ import { queueWatcher } from '../core/observer/scheduler'
18+ import { TrackOpTypes , TriggerOpTypes } from './reactivity/operations'
2219
2320const WATCHER = `watcher`
2421const WATCHER_CB = `${ WATCHER } callback`
@@ -58,6 +55,19 @@ export interface DebuggerOptions {
5855 onTrigger ?: ( event : DebuggerEvent ) => void
5956}
6057
58+ export type DebuggerEvent = {
59+ watcher : Watcher
60+ } & DebuggerEventExtraInfo
61+
62+ export type DebuggerEventExtraInfo = {
63+ target : object
64+ type : TrackOpTypes | TriggerOpTypes
65+ key : any
66+ newValue ?: any
67+ oldValue ?: any
68+ oldTarget ?: Map < any , any > | Set < any >
69+ }
70+
6171export interface WatchOptions < Immediate = boolean > extends WatchOptionsBase {
6272 immediate ?: Immediate
6373 deep ?: boolean
@@ -162,7 +172,13 @@ export function watch<T = any, Immediate extends Readonly<boolean> = false>(
162172function doWatch (
163173 source : WatchSource | WatchSource [ ] | WatchEffect | object ,
164174 cb : WatchCallback | null ,
165- { immediate, deep, flush, onTrack, onTrigger } : WatchOptions = emptyObject
175+ {
176+ immediate,
177+ deep,
178+ flush = 'pre' ,
179+ onTrack,
180+ onTrigger
181+ } : WatchOptions = emptyObject
166182) : WatchStopHandle {
167183 if ( __DEV__ && ! cb ) {
168184 if ( immediate !== undefined ) {
@@ -200,7 +216,12 @@ function doWatch(
200216 getter = ( ) => source . value
201217 forceTrigger = isShallow ( source )
202218 } else if ( isReactive ( source ) ) {
203- getter = ( ) => source
219+ getter = isArray ( source )
220+ ? ( ) => {
221+ ; ( source as any ) . __ob__ . dep . depend ( )
222+ return source
223+ }
224+ : ( ) => source
204225 deep = true
205226 } else if ( isArray ( source ) ) {
206227 isMultiSource = true
@@ -245,7 +266,7 @@ function doWatch(
245266
246267 let cleanup : ( ) => void
247268 let onCleanup : OnCleanup = ( fn : ( ) => void ) => {
248- cleanup = effect . onStop = ( ) => {
269+ cleanup = watcher . onStop = ( ) => {
249270 call ( fn , WATCHER_CLEANUP )
250271 }
251272 }
@@ -267,14 +288,23 @@ function doWatch(
267288 return noop
268289 }
269290
291+ const watcher = new Watcher ( currentInstance , getter , noop , {
292+ lazy : true
293+ } )
294+ watcher . noRecurse = ! cb
295+
270296 let oldValue = isMultiSource ? [ ] : INITIAL_WATCHER_VALUE
271- const job = ( ) => {
272- if ( ! effect . active ) {
297+ // overwrite default run
298+ watcher . run = ( ) => {
299+ if (
300+ ! watcher . active &&
301+ ! ( flush === 'pre' && instance && instance . _isBeingDestroyed )
302+ ) {
273303 return
274304 }
275305 if ( cb ) {
276306 // watch(source, cb)
277- const newValue = effect . run ( )
307+ const newValue = watcher . get ( )
278308 if (
279309 deep ||
280310 forceTrigger ||
@@ -298,52 +328,51 @@ function doWatch(
298328 }
299329 } else {
300330 // watchEffect
301- effect . run ( )
331+ watcher . get ( )
302332 }
303333 }
304334
305- let scheduler : EffectScheduler
306335 if ( flush === 'sync' ) {
307- scheduler = job as any // the scheduler function gets called directly
336+ watcher . update = watcher . run
308337 } else if ( flush === 'post' ) {
309- scheduler = ( ) => queuePostRenderEffect ( job )
338+ watcher . id = Infinity
339+ watcher . update = ( ) => queueWatcher ( watcher )
310340 } else {
311- // default: 'pre'
312- scheduler = ( ) => queuePreFlushCb ( job )
341+ // pre
342+ watcher . update = ( ) => {
343+ if ( ! instance || instance . _isMounted ) {
344+ queueWatcher ( watcher )
345+ } else {
346+ const buffer = instance . _preWatchers || ( instance . _preWatchers = [ ] )
347+ if ( buffer . indexOf ( watcher ) < 0 ) buffer . push ( watcher )
348+ }
349+ }
313350 }
314351
315- const effect = new ReactiveEffect ( getter , scheduler )
316-
317- if ( __DEV__ ) {
318- effect . onTrack = onTrack
319- effect . onTrigger = onTrigger
320- }
352+ // TODO
353+ // if (__DEV__) {
354+ // effect.onTrack = onTrack
355+ // effect.onTrigger = onTrigger
356+ // }
321357
322358 // initial run
323359 if ( cb ) {
324360 if ( immediate ) {
325- job ( )
361+ watcher . run ( )
326362 } else {
327- oldValue = effect . run ( )
363+ oldValue = watcher . get ( )
328364 }
329- } else if ( flush === 'post' ) {
330- queuePostRenderEffect ( effect . run . bind ( effect ) )
365+ } else if ( flush === 'post' && instance ) {
366+ instance . $once ( 'hook:mounted' , ( ) => watcher . get ( ) )
331367 } else {
332- effect . run ( )
368+ watcher . get ( )
333369 }
334370
335371 return ( ) => {
336- effect . stop ( )
337- if ( instance && instance . scope ) {
338- remove ( instance . scope . effects ! , effect )
339- }
372+ watcher . teardown ( )
373+ // TODO
374+ // if (instance && instance.scope) {
375+ // remove(instance.scope.effects!, effect)
376+ // }
340377 }
341378}
342-
343- function queuePostRenderEffect ( fn : Function ) {
344- // TODO
345- }
346-
347- function queuePreFlushCb ( fn : Function ) {
348- // TODO
349- }
0 commit comments