From b4c909c260f8028acad97f4bbd207ef02e9cfc03 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 3 Sep 2019 23:04:11 -0400 Subject: [PATCH] feat: $nextTick, $forceUpdate, $watch --- packages/runtime-core/src/apiOptions.ts | 21 ++++++++++++++++----- packages/runtime-core/src/componentProxy.ts | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/runtime-core/src/apiOptions.ts b/packages/runtime-core/src/apiOptions.ts index 2ab2af29f..6c87daccb 100644 --- a/packages/runtime-core/src/apiOptions.ts +++ b/packages/runtime-core/src/apiOptions.ts @@ -13,7 +13,7 @@ import { EMPTY_OBJ } from '@vue/shared' import { computed, ComputedOptions } from './apiReactivity' -import { watch } from './apiWatch' +import { watch, WatchOptions } from './apiWatch' import { provide, inject } from './apiInject' import { onBeforeMount, @@ -133,10 +133,8 @@ export function processOptions(instance: ComponentInstance) { } else if (isFunction(raw)) { watch(getter, raw.bind(ctx)) } else if (isObject(raw)) { - watch(getter, raw.handler.bind(ctx), { - deep: !!raw.deep, - lazy: !raw.immediate - }) + // TODO 2.x compat + watch(getter, raw.handler.bind(ctx), raw) } else if (__DEV__) { // TODO warn invalid watch options } @@ -201,3 +199,16 @@ export function processOptions(instance: ComponentInstance) { onUnmounted(destroyed.bind(ctx)) } } + +export function legacyWatch( + this: ComponentInstance, + source: string | Function, + cb: Function, + options?: WatchOptions +): () => void { + const ctx = this.renderProxy as any + const getter = isString(source) ? () => ctx[source] : source.bind(ctx) + const stop = watch(getter, cb.bind(ctx), options) + onBeforeMount(stop, this) + return stop +} diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index c67244e90..16d1a0e1c 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -1,4 +1,6 @@ import { ComponentInstance } from './component' +import { nextTick } from './scheduler' +import { legacyWatch } from './apiOptions' export const RenderProxyHandlers = { get(target: ComponentInstance, key: string) { @@ -26,7 +28,23 @@ export const RenderProxyHandlers = { return target.root case '$emit': return target.emit + case '$el': + return target.vnode.el + case '$options': + // TODO handle merging + return target.type default: + // methods are only exposed when options are supported + if (__FEATURE_OPTIONS__) { + switch (key) { + case '$forceUpdate': + return target.update + case '$nextTick': + return nextTick + case '$watch': + return legacyWatch.bind(target) + } + } return target.user[key] } }