From b5f91ff570244436aa8f579ec3a6fec781d198a7 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 4 Aug 2020 18:42:47 +0200 Subject: [PATCH] fix(watch): allow handler to be a string (#1775) fix #1774 --- .../runtime-core/__tests__/apiOptions.spec.ts | 23 ++++++++++++++++--- packages/runtime-core/src/componentOptions.ts | 11 +++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/runtime-core/__tests__/apiOptions.spec.ts b/packages/runtime-core/__tests__/apiOptions.spec.ts index 37fb3635..95fed1d7 100644 --- a/packages/runtime-core/__tests__/apiOptions.spec.ts +++ b/packages/runtime-core/__tests__/apiOptions.spec.ts @@ -112,6 +112,7 @@ describe('api: options', () => { const spyA = jest.fn(returnThis) const spyB = jest.fn(returnThis) const spyC = jest.fn(returnThis) + const spyD = jest.fn(returnThis) let ctx: any const Comp = { @@ -121,7 +122,8 @@ describe('api: options', () => { bar: 2, baz: { qux: 3 - } + }, + qux: 4 } }, watch: { @@ -132,10 +134,14 @@ describe('api: options', () => { baz: { handler: spyC, deep: true + }, + qux: { + handler: 'onQuxChange' } }, methods: { - onFooChange: spyA + onFooChange: spyA, + onQuxChange: spyD }, render() { ctx = this @@ -164,6 +170,11 @@ describe('api: options', () => { expect(spyC).toHaveBeenCalledTimes(1) // new and old objects have same identity assertCall(spyC, 0, [{ qux: 4 }, { qux: 4 }]) + + ctx.qux++ + await nextTick() + expect(spyD).toHaveBeenCalledTimes(1) + assertCall(spyD, 0, [5, 4]) }) test('watch array', async () => { @@ -707,7 +718,10 @@ describe('api: options', () => { test('Expected a function as watch handler', () => { const Comp = { watch: { - foo: 'notExistingMethod' + foo: 'notExistingMethod', + foo2: { + handler: 'notExistingMethod2' + } }, render() {} } @@ -718,6 +732,9 @@ describe('api: options', () => { expect( 'Invalid watch handler specified by key "notExistingMethod"' ).toHaveBeenWarned() + expect( + 'Invalid watch handler specified by key "notExistingMethod2"' + ).toHaveBeenWarned() }) test('Invalid watch option', () => { diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 29b16f0e..72fffe24 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -266,7 +266,7 @@ export type ExtractComputedReturns = { type WatchOptionItem = | string | WatchCallback - | { handler: WatchCallback } & WatchOptions + | { handler: WatchCallback | string } & WatchOptions type ComponentWatchOptionItem = WatchOptionItem | WatchOptionItem[] @@ -704,7 +704,14 @@ function createWatcher( if (isArray(raw)) { raw.forEach(r => createWatcher(r, ctx, publicThis, key)) } else { - watch(getter, raw.handler.bind(publicThis), raw) + const handler = isFunction(raw.handler) + ? raw.handler.bind(publicThis) + : (ctx[raw.handler] as WatchCallback) + if (isFunction(handler)) { + watch(getter, handler, raw) + } else if (__DEV__) { + warn(`Invalid watch handler specified by key "${raw.handler}"`, handler) + } } } else if (__DEV__) { warn(`Invalid watch option: "${key}"`)