From d3fe492d7e6ea3c677517d463d7887a0c8eebdcb Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 6 Jun 2019 15:19:04 +0800 Subject: [PATCH] wip: adjust watcher cleanup api --- packages/observer/__tests__/computed.spec.ts | 19 ++----- packages/runtime-core/src/reactivity.ts | 53 ++++++++++---------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/packages/observer/__tests__/computed.spec.ts b/packages/observer/__tests__/computed.spec.ts index 6fef5d30b..e9ef8d578 100644 --- a/packages/observer/__tests__/computed.spec.ts +++ b/packages/observer/__tests__/computed.spec.ts @@ -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 + }) }) diff --git a/packages/runtime-core/src/reactivity.ts b/packages/runtime-core/src/reactivity.ts index 4c28185a3..12adfc128 100644 --- a/packages/runtime-core/src/reactivity.ts +++ b/packages/runtime-core/src/reactivity.ts @@ -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( source: Value | (() => T), - cb?: (newValue: V, oldValue: V) => (() => void) | void, - options: WatchOptions = EMPTY_OBJ + cb?: ( + 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( 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()