为什么将v-on:click =“ method()”像v-on:click =“ method”一样视为方法声明?

时间:2018-07-21 19:55:28

标签: javascript vue.js

考虑此示例https://codesandbox.io/s/1yvp4zz5x7?module=%2Fsrc%2FApp.vue

<template>
  <div>
    <button v-on:click="method">Greet1</button>
    <button v-on:click="method()">Greet2</button>
  </div>  
</template>

<script>
  export default {
    methods: {
      method() {
        alert('Hello');
      }
    }
  };
</script>

这两个按钮的工作原理完全相同(我知道第一个示例中的传递事件),尽管事实是在“ Greet1”中的v-on:click中有方法声明,而在“ Greet2”有方法调用

在组件渲染阶段“ Greet2”是否不会显示警报,并且该按钮不应在单击时起作用,因为我没有在method()中返回功能?

为什么这里有这种机制及其作用方式?

1 个答案:

答案 0 :(得分:3)

不会立即调用该方法,因为在渲染模板之前,它将被编译为一个函数。在编译过程中,v-on click表达式由Vue解析并以两种单独的方式进行处理。本质上,在

情况下编译模板时会发生什么
<button v-on:click="method">Greet1</button>

是单击处理程序直接设置为method。对于

<button v-on:click="method()">Greet2</button>

点击处理程序设置为

function($event) { method() }

将整个编译后的渲染函数包装在with(this)中,以便正确解析method()和以这种方式声明的其他内容。

这里有一个小片段from the generated code,显示了如何确定。

var fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;
var simplePathRE = /^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?']|\[".*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*\s*$/;

...many lines omitted...

var isMethodPath = simplePathRE.test(handler.value);
var isFunctionExpression = fnExpRE.test(handler.value);

if (!handler.modifiers) {
  if (isMethodPath || isFunctionExpression) {
    return handler.value
  }

  return ("function($event){" + (handler.value) + "}") // inline statement
}

如果您仔细阅读了上面链接的代码,则相关功能为genHandler(对于Vue的特定版本为2.5.13)。