Vue 的事件传参

起因是突然想起了 vue 绑定事件,好像默认情况下不能带有括号,不过如果要传参的话,就必须带有括号了。很难理解。特意今天测试了下,结果发现都兼容了。

直接上例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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)}}

我怎么记得以前是检查是否有括号…逻辑可比这个简单多了…

不过现在的样子逻辑也挺清晰的,唯独就是看不懂正则…

–END–