Vue 的事件传参
· 阅读需 3 分钟
起因是突然想起了 vue 绑定事件,好像默认情况下不能带有括号,不过如果要传参的话,就必须带有括号了。很难理解。特意今天测试了下,结果发现都兼容了。
直接上例子
<template>
<div>
<p @click="onClick">click1</p>
<p @click="onClick()">click2</p>
<p @click="onClick('click3')">click3</p>
<p @click="onClick($event, 'click4')">click4</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {};
},
methods: {
onClick(event, val) {
console.log("!!!", event, val);
}
}
};
</script>
click1 是最简单最标准的绑定事件。默认情况下,第一个参数就是 event
,无需我们自己按照 click4 的方式再写出来。
click2 我记得很早之前不能这样写,会报错。现在不会报错了,但是强制指定了参数(为空),所以什么参数都获取不到。
click3、click4 是常规的写法,如果主动声明参数(自定义传值),那么必须这么写,clcik3 和 click4 区别就是一个指定了 $event
,另一个没有而已。此外,这个 $event
不一定放在第一个参数位置,第二个参数啥的都可以。
突然发现,自己太水了...
查阅源代码
src\compiler\codegen\events.js
const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/
const fnInvokeRE = /\([^)]*?\);*$/
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
// ...
const isMethodPath = simplePathRE.test(handler.value)
const isFunctionExpression = fnExpRE.test(handler.value)
const isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''))
if (!handler.modifiers) {
if (isMethodPath || isFunctionExpression) {
return handler.value
}
// ...
return `function($event){${
isFunctionInvocation ? `return ${handler.value}` : handler.value
}}` // inline statement
}
// simplePathRE 这个正则太复杂了,我是肯定理解不了的...
// 不过:
// 如果是 @click="onClick"
// isMethodPath 为 true,直接返回
// 最终结果变成 on:{"click":onClick}
// 如果是 @click="onClick($event)"
// isMethodPath 为 false,返回一个函数字符串
// 最终结果变成 on:{"click":function($event){return onClick($event)}}
我怎么记得以前是检查是否有括号...逻辑可比这个简单多了...
不过现在的样子逻辑也挺清晰的,唯独就是看不懂正则...