瀏覽代碼

fix(watch): allow handler to be a string (#1775)

fix #1774
Eduardo San Martin Morote 5 年之前
父節點
當前提交
b5f91ff570
共有 2 個文件被更改,包括 29 次插入5 次删除
  1. 20 3
      packages/runtime-core/__tests__/apiOptions.spec.ts
  2. 9 2
      packages/runtime-core/src/componentOptions.ts

+ 20 - 3
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', () => {

+ 9 - 2
packages/runtime-core/src/componentOptions.ts

@@ -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}"`)