v-on绑定事件函数为什么可以加括号传参
v-on:vue的事件处理器
缩写:@
预期:Function | Inline Statement | Object
参数:event
修饰符:
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
v-on
中既可以执行一段代码、一个方法、内联 JavaScript 语句,根据不同的情况 Vue 会做不同的处理,具体可以从源码中可以看出(2.1.10版本)
在编译阶段,会根据抽象HTML语法树生成代码,从 https://github.com/vuejs/vue/blob/v2.1.10/src/compiler/codegen/index.js#L194 可以看出如果此时包含了事件处理,则会调用 genHandlers
生成事件处理代码,最终走到 https://github.com/vuejs/vue/blob/v2.1.10/src/compiler/codegen/events.js#L46 ,这里有两个正则判断,判断是函数正则以及属性访问正则,如果两个正则匹配成功则直接返回当前的值,否则用 function($event){${handler.value}}
包裹一次。
如果说你是直接给定的 greet
的话,则属性访问正则匹配成功,如果是greet()
或者 x+=1
来说,则两个正则都匹配失败,利用函数包裹一层;而额外的第一种判断函数的正则则只有是你写的是函数的时候才会匹配成功,也就是类似于 function () {xxx}
或者 () => dsf
也就是一个匿名函数或者箭头函数。
最后,到底需不需要加括号的话,一般就是要看参数的情况了:
-
不需要参数或者默认参数的情况下,用一个定义的方法名即可。此时有一个需要注意的就是默认参数的情况,对于原生的事件处理的话,参数就只有一个:事件对象event;而对于自定义事件的话,则是在 emit 的时候传入的参数是什么,这个定义的方法被调用的时候的参数也是一一对应的。
-
自定义参数,这个参数有可能是你在HTML上直接写的
greet('xx')
,也有可能是在特殊上下文中得到的,例如说在v-for
内部,可以传入当前循环项;这种情况下则是当一段代码片段来执行的,此时正是因为包裹的函数是有$event
参数的,所以可以使用这个;你可能还会发现此时还可以这样写:greet(arguments)
,传入的就是arguments
对象,把调用定义方法的参数在形式上是可以由多个变为一个的。