From 1c9a0b3e195d144ac90d22d2cc2cef6a3fd8276d Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 18 Sep 2020 00:00:39 -0400 Subject: [PATCH] feat(watch): support dot-delimited path in watch option --- .../runtime-core/__tests__/apiOptions.spec.ts | 14 ++++++++++++-- packages/runtime-core/src/componentOptions.ts | 17 +++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/apiOptions.spec.ts b/packages/runtime-core/__tests__/apiOptions.spec.ts index 00ecb6e4c4c..6b6014c05cc 100644 --- a/packages/runtime-core/__tests__/apiOptions.spec.ts +++ b/packages/runtime-core/__tests__/apiOptions.spec.ts @@ -113,6 +113,7 @@ describe('api: options', () => { const spyB = jest.fn(returnThis) const spyC = jest.fn(returnThis) const spyD = jest.fn(returnThis) + const spyE = jest.fn(returnThis) let ctx: any const Comp = { @@ -123,7 +124,10 @@ describe('api: options', () => { baz: { qux: 3 }, - qux: 4 + qux: 4, + dot: { + path: 5 + } } }, watch: { @@ -137,7 +141,8 @@ describe('api: options', () => { }, qux: { handler: 'onQuxChange' - } + }, + 'dot.path': spyE }, methods: { onFooChange: spyA, @@ -175,6 +180,11 @@ describe('api: options', () => { await nextTick() expect(spyD).toHaveBeenCalledTimes(1) assertCall(spyD, 0, [5, 4]) + + ctx.dot.path++ + await nextTick() + expect(spyE).toHaveBeenCalledTimes(1) + assertCall(spyE, 0, [6, 5]) }) test('watch array', async () => { diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index ff499d36cdc..0ff710c36c6 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -816,7 +816,9 @@ function createWatcher( publicThis: ComponentPublicInstance, key: string ) { - const getter = () => (publicThis as any)[key] + const getter = key.includes('.') + ? createPathGetter(publicThis, key) + : () => (publicThis as any)[key] if (isString(raw)) { const handler = ctx[raw] if (isFunction(handler)) { @@ -840,7 +842,18 @@ function createWatcher( } } } else if (__DEV__) { - warn(`Invalid watch option: "${key}"`) + warn(`Invalid watch option: "${key}"`, raw) + } +} + +function createPathGetter(ctx: any, path: string) { + const segments = path.split('.') + return () => { + let cur = ctx + for (let i = 0; i < segments.length && cur; i++) { + cur = cur[segments[i]] + } + return cur } }