v-on的思考

某位面试官为了一个问题, v-on可以绑定几个函数

正常来想, v-on不是只一个函数吗, 还可以绑定多个?

正确答案: 无数个

vue 复制代码
<div @click="handle1(), handle2(), handle3() ..."></div>

<!-- or -->

<div @click="[handle1(), handle2(), handle3()]"></div>

<!-- but 上面的方法中不写括号是不行的 -->

为什么会成这样的问题呢?

看文档

文档上说

md 复制代码
v-on​

给元素绑定事件监听器。

缩写:@

期望的绑定值类型:`Function | Inline Statement | Object (不带参数)`

类型中的 Function可以理解, 就是最常用的直接传递函数

Object类型主要指的是一个v-on绑定多个事件(不常用)

vue 复制代码
<!-- 对象语法 -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

那么这个Inline Statement是个什么类型, 这也是这里主要探讨的地方

看编译

详情

vue 复制代码
<div @click="handle1(), handle2(), handle3() ..."></div>
js 复制代码
// 完整编译结果, 后面省略重复部分 // [!code focus]
_createElementVNode("button", {
  onClick: _cache[0] || (_cache[0] = $event => ($setup.handle1(), $setup.handle2(), $setup.handle3())) // [!code focus]
}),

其实 <div @click="handle1(), handle2(), handle3() ..."></div> 就是上面的 Inline Statement 类型

编译器会将 handle1(), handle2(), handle3() ... 当作一个语句, 然后再触发事件是运行这个语句

数组写法同理

vue 复制代码
<div @click="[handle1(), handle2(), handle3()]"></div>
js 复制代码
// 数组编译结果
;($event) => [$setup.handle1(), $setup.handle2(), $setup.handle3()]

甚至可以在里面写任何东西

vue 复制代码
<div @click="{ handle1 }"></div>
js 复制代码
// 编译结果
;($event) => ({ handle1: $setup.handle1 })

这也解释了为什么不加括号不生效的原因, 因为当这个事件触发时, 语句运行了, 但是函数因为没有括号而没有被调用

js 复制代码
// 无括号编译结果
;($event) => ($setup.handle1, $setup.handle2, $setup.handle3)

为什么编译后的结果是这样的呢

看源码

差不多的意思就是说, 如果判断出来是一个inline statement, 那么就拼接一个函数, inline statement就是函数体

顺便一提, inline statement 支持多行, 意思就是说, 这里可以写分号, 编译出来就是多行

vue 复制代码
<!-- prettier-ignore -->
<div @click="handle1(); handle2(); handle3()"></div>
js 复制代码
// 编译结果
// prettier-ignore
;$event => {$setup.log(); $setup.log()}

思考

所以为什么如果只传函数的话可以加括号也可以不加

因为如果加了括号就是一个inline statement

js 复制代码
;($event) => $setup.handle1()

如果不加括号就是一个函数, 会把这个函数直接传递个事件

js 复制代码
_createElementVNode('button', { onClick: $setup.log })
相关推荐
hedley(●'◡'●)23 分钟前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
qq5_81151751525 分钟前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育26 分钟前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
百锦再26 分钟前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
CappuccinoRose1 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明
这儿有一堆花1 小时前
Vue 是什么:一套为「真实业务」而生的前端框架
前端·vue.js·前端框架
全栈前端老曹1 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
NCDS程序员2 小时前
v-model: /v-model/ :(v-bind)三者核心区别
前端·javascript·vue.js
夏幻灵2 小时前
CSS三大特性:层叠、继承与优先级解析
前端·css
小杨同学呀呀呀呀2 小时前
Ant Design Vue <a-timeline>时间轴组件失效解决方案
前端·javascript·vue.js·typescript·anti-design-vue