Просмотр исходного кода

fix: return inline invocation return value in v-on handlers

close #7628
Evan You 7 лет назад
Родитель
Сommit
0ebb0f39df
2 измененных файлов с 32 добавлено и 2 удалено
  1. 8 2
      src/compiler/codegen/events.js
  2. 24 0
      test/unit/features/directives/on.spec.js

+ 8 - 2
src/compiler/codegen/events.js

@@ -1,6 +1,7 @@
 /* @flow */
 
 const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/
+const fnInvokeRE = /\([^)]*?\)$/
 const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
 
 // KeyboardEvent.keyCode aliases
@@ -94,6 +95,7 @@ function genHandler (
 
   const isMethodPath = simplePathRE.test(handler.value)
   const isFunctionExpression = fnExpRE.test(handler.value)
+  const isFunctionInvocation = fnInvokeRE.test(handler.value)
 
   if (!handler.modifiers) {
     if (isMethodPath || isFunctionExpression) {
@@ -103,7 +105,9 @@ function genHandler (
     if (__WEEX__ && handler.params) {
       return genWeexHandler(handler.params, handler.value)
     }
-    return `function($event){${handler.value}}` // inline statement
+    return `function($event){${
+      isFunctionInvocation ? `return (${handler.value})` : handler.value
+    }}` // inline statement
   } else {
     let code = ''
     let genModifierCode = ''
@@ -138,7 +142,9 @@ function genHandler (
       ? `return ${handler.value}($event)`
       : isFunctionExpression
         ? `return (${handler.value})($event)`
-        : handler.value
+        : isFunctionInvocation
+          ? `return (${handler.value})`
+          : handler.value
     /* istanbul ignore if */
     if (__WEEX__ && handler.params) {
       return genWeexHandler(handler.params, code + handlerCode)

+ 24 - 0
test/unit/features/directives/on.spec.js

@@ -923,4 +923,28 @@ describe('Directive v-on', () => {
       expect(spy.calls.count()).toBe(0)
     }).then(done)
   })
+
+  // #7628
+  it('handler should return the return value of inline function invocation', () => {
+    let value
+    new Vue({
+      template: `<test @foo="bar()"></test>`,
+      methods: {
+        bar() {
+          return 1
+        }
+      },
+      components: {
+        test: {
+          created() {
+            value = this.$listeners.foo()
+          },
+          render(h) {
+            return h('div')
+          }
+        }
+      }
+    }).$mount()
+    expect(value).toBe(1)
+  })
 })