Reputation: 16039
Consider this example 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>
Both buttons will work exactly the same (I'm aware of passing event in the first example) despite the fact that in v-on:click
in "Greet1" there is method declaration and in "Greet2" there is method invokation.
Shouldn't "Greet2" display alert during component rendering phase and this button shouldn't work on clicking since I didn't return function in method()
?
Why there is this mechanism here and how it works?
Upvotes: 3
Views: 86
Reputation: 82459
The method is not called immediately, because before the template is ever rendered, it is compiled into a function. During the compilation process, the v-on
click expression is parsed by Vue and handled in two separate ways. Essentially, what happens when the template is compiled in the case of
<button v-on:click="method">Greet1</button>
is that the click handler is set directly to method
. In the case of
<button v-on:click="method()">Greet2</button>
the click handler is set to
function($event) { method() }
The entire compiled render function is wrapped in a with(this)
so that method()
and other things that are declared that way are resolved properly.
Here is a little snippet from the generated code that shows how this is decided.
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
}
If you read through the code of the above link, the function in question is genHandler
(for this particular version of Vue, which is 2.5.13).
Upvotes: 3