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)
|
||||
})
|
||||
|
||||
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', () => {
|
||||
const value: any = observable({})
|
||||
const cValue = computed(() => value.foo)
|
||||
@ -136,4 +121,8 @@ describe('observer/computed', () => {
|
||||
value.foo = 2
|
||||
expect(dummy).toBe(1)
|
||||
})
|
||||
|
||||
it('should support setter', () => {
|
||||
// TODO
|
||||
})
|
||||
})
|
||||
|
@ -31,7 +31,7 @@ import {
|
||||
} from '@vue/observer'
|
||||
import { currentInstance } from './component'
|
||||
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
|
||||
// stopped when the component unmounts
|
||||
@ -63,39 +63,38 @@ const invoke = (fn: Function) => fn()
|
||||
|
||||
export function watch<T>(
|
||||
source: Value<T> | (() => T),
|
||||
cb?: <V extends T>(newValue: V, oldValue: V) => (() => void) | void,
|
||||
options: WatchOptions = EMPTY_OBJ
|
||||
cb?: <V extends T>(
|
||||
newValue: V,
|
||||
oldValue: V,
|
||||
onInvalidate: (fn: () => void) => void
|
||||
) => any | void,
|
||||
{ lazy, flush, deep, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
|
||||
): () => void {
|
||||
const scheduler =
|
||||
options.flush === 'sync'
|
||||
? invoke
|
||||
: options.flush === 'pre'
|
||||
? queueJob
|
||||
: queuePostFlushCb
|
||||
flush === 'sync' ? invoke : flush === 'pre' ? queueJob : queuePostFlushCb
|
||||
|
||||
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 cleanup: any
|
||||
const applyCb = cb
|
||||
? () => {
|
||||
const newValue = runner()
|
||||
if (options.deep || newValue !== oldValue) {
|
||||
try {
|
||||
// cleanup before running cb again
|
||||
if (cleanup) {
|
||||
cleanup()
|
||||
}
|
||||
const _cleanup = cb(newValue, oldValue)
|
||||
if (isFunction(_cleanup)) {
|
||||
// save cleanup so it is also called when effect is stopped
|
||||
cleanup = runner.onStop = _cleanup
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO handle error
|
||||
// handleError(e, instance, ErrorTypes.WATCH_CALLBACK)
|
||||
if (deep || newValue !== oldValue) {
|
||||
// cleanup before running cb again
|
||||
if (cleanup) {
|
||||
cleanup()
|
||||
}
|
||||
// TODO handle error (including ASYNC)
|
||||
try {
|
||||
cb(newValue, oldValue, registerCleanup)
|
||||
} catch (e) {}
|
||||
oldValue = newValue
|
||||
}
|
||||
}
|
||||
@ -105,12 +104,12 @@ export function watch<T>(
|
||||
lazy: true,
|
||||
// so it runs before component update effects in pre flush mode
|
||||
computed: true,
|
||||
onTrack: options.onTrack,
|
||||
onTrigger: options.onTrigger,
|
||||
onTrack,
|
||||
onTrigger,
|
||||
scheduler: applyCb ? () => scheduler(applyCb) : void 0
|
||||
})
|
||||
|
||||
if (!options.lazy) {
|
||||
if (!lazy) {
|
||||
applyCb && scheduler(applyCb)
|
||||
} else {
|
||||
oldValue = runner()
|
||||
|
Loading…
Reference in New Issue
Block a user