wip: adjust watcher cleanup api
This commit is contained in:
parent
1d41771e56
commit
d3fe492d7e
@ -37,21 +37,6 @@ describe('observer/computed', () => {
|
|||||||
expect(getter).toHaveBeenCalledTimes(2)
|
expect(getter).toHaveBeenCalledTimes(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should accept context', () => {
|
|
||||||
const value: any = observable({})
|
|
||||||
let callCtx, callArg
|
|
||||||
const getter = function(arg: any) {
|
|
||||||
callCtx = this
|
|
||||||
callArg = arg
|
|
||||||
return value.foo
|
|
||||||
}
|
|
||||||
const ctx = {}
|
|
||||||
const cValue = computed(getter, ctx)
|
|
||||||
cValue.value
|
|
||||||
expect(callCtx).toBe(ctx)
|
|
||||||
expect(callArg).toBe(ctx)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should trigger effect', () => {
|
it('should trigger effect', () => {
|
||||||
const value: any = observable({})
|
const value: any = observable({})
|
||||||
const cValue = computed(() => value.foo)
|
const cValue = computed(() => value.foo)
|
||||||
@ -136,4 +121,8 @@ describe('observer/computed', () => {
|
|||||||
value.foo = 2
|
value.foo = 2
|
||||||
expect(dummy).toBe(1)
|
expect(dummy).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should support setter', () => {
|
||||||
|
// TODO
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -31,7 +31,7 @@ import {
|
|||||||
} from '@vue/observer'
|
} from '@vue/observer'
|
||||||
import { currentInstance } from './component'
|
import { currentInstance } from './component'
|
||||||
import { queueJob, queuePostFlushCb } from './scheduler'
|
import { queueJob, queuePostFlushCb } from './scheduler'
|
||||||
import { EMPTY_OBJ, isObject, isArray, isFunction } from '@vue/shared'
|
import { EMPTY_OBJ, isObject, isArray } from '@vue/shared'
|
||||||
|
|
||||||
// record effects created during a component's setup() so that they can be
|
// record effects created during a component's setup() so that they can be
|
||||||
// stopped when the component unmounts
|
// stopped when the component unmounts
|
||||||
@ -63,39 +63,38 @@ const invoke = (fn: Function) => fn()
|
|||||||
|
|
||||||
export function watch<T>(
|
export function watch<T>(
|
||||||
source: Value<T> | (() => T),
|
source: Value<T> | (() => T),
|
||||||
cb?: <V extends T>(newValue: V, oldValue: V) => (() => void) | void,
|
cb?: <V extends T>(
|
||||||
options: WatchOptions = EMPTY_OBJ
|
newValue: V,
|
||||||
|
oldValue: V,
|
||||||
|
onInvalidate: (fn: () => void) => void
|
||||||
|
) => any | void,
|
||||||
|
{ lazy, flush, deep, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
|
||||||
): () => void {
|
): () => void {
|
||||||
const scheduler =
|
const scheduler =
|
||||||
options.flush === 'sync'
|
flush === 'sync' ? invoke : flush === 'pre' ? queueJob : queuePostFlushCb
|
||||||
? invoke
|
|
||||||
: options.flush === 'pre'
|
|
||||||
? queueJob
|
|
||||||
: queuePostFlushCb
|
|
||||||
|
|
||||||
const baseGetter = isValue(source) ? () => source.value : source
|
const baseGetter = isValue(source) ? () => source.value : source
|
||||||
const getter = options.deep ? () => traverse(baseGetter()) : baseGetter
|
const getter = deep ? () => traverse(baseGetter()) : baseGetter
|
||||||
|
|
||||||
|
let cleanup: any
|
||||||
|
const registerCleanup = (fn: () => void) => {
|
||||||
|
// TODO wrap the cleanup fn for error handling
|
||||||
|
cleanup = runner.onStop = fn
|
||||||
|
}
|
||||||
|
|
||||||
let oldValue: any
|
let oldValue: any
|
||||||
let cleanup: any
|
|
||||||
const applyCb = cb
|
const applyCb = cb
|
||||||
? () => {
|
? () => {
|
||||||
const newValue = runner()
|
const newValue = runner()
|
||||||
if (options.deep || newValue !== oldValue) {
|
if (deep || newValue !== oldValue) {
|
||||||
try {
|
|
||||||
// cleanup before running cb again
|
// cleanup before running cb again
|
||||||
if (cleanup) {
|
if (cleanup) {
|
||||||
cleanup()
|
cleanup()
|
||||||
}
|
}
|
||||||
const _cleanup = cb(newValue, oldValue)
|
// TODO handle error (including ASYNC)
|
||||||
if (isFunction(_cleanup)) {
|
try {
|
||||||
// save cleanup so it is also called when effect is stopped
|
cb(newValue, oldValue, registerCleanup)
|
||||||
cleanup = runner.onStop = _cleanup
|
} catch (e) {}
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// TODO handle error
|
|
||||||
// handleError(e, instance, ErrorTypes.WATCH_CALLBACK)
|
|
||||||
}
|
|
||||||
oldValue = newValue
|
oldValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,12 +104,12 @@ export function watch<T>(
|
|||||||
lazy: true,
|
lazy: true,
|
||||||
// so it runs before component update effects in pre flush mode
|
// so it runs before component update effects in pre flush mode
|
||||||
computed: true,
|
computed: true,
|
||||||
onTrack: options.onTrack,
|
onTrack,
|
||||||
onTrigger: options.onTrigger,
|
onTrigger,
|
||||||
scheduler: applyCb ? () => scheduler(applyCb) : void 0
|
scheduler: applyCb ? () => scheduler(applyCb) : void 0
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!options.lazy) {
|
if (!lazy) {
|
||||||
applyCb && scheduler(applyCb)
|
applyCb && scheduler(applyCb)
|
||||||
} else {
|
} else {
|
||||||
oldValue = runner()
|
oldValue = runner()
|
||||||
|
Loading…
Reference in New Issue
Block a user