]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(watch): allow handler to be a string (#1775)
authorEduardo San Martin Morote <posva@users.noreply.github.com>
Tue, 4 Aug 2020 16:42:47 +0000 (18:42 +0200)
committerGitHub <noreply@github.com>
Tue, 4 Aug 2020 16:42:47 +0000 (12:42 -0400)
fix #1774

packages/runtime-core/__tests__/apiOptions.spec.ts
packages/runtime-core/src/componentOptions.ts

index 37fb36357bebd1c93641726a4a35ef34427fd791..95fed1d7fd270b3fd81ca52d6a6c90b64682264f 100644 (file)
@@ -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', () => {
index 29b16f0ed89d2a2de068316b08c142ccec373cbc..72fffe241e8deca896e398acff294e0d63c6e151 100644 (file)
@@ -266,7 +266,7 @@ export type ExtractComputedReturns<T extends any> = {
 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}"`)