v-on 是 Vue 的事件绑定指令,近期在使用Vxe Table组件库的时候看见了一个就职公司项目场景不常用的写法,在此分享给同样不常用或不知道的同学们。
//此处复制的是vxetbale组件库的示例代码
<vxe-grid v-bind="gridOptions" v-on="gridEvents"></vxe-grid>
const gridEvents: VxeGridListeners = {
pageChange ({ pageSize, currentPage }) {
pagerVO.currentPage = currentPage
pagerVO.pageSize = pageSize
loadList()
}
}
v-on绝大部分人只知道是vue提供的事件绑定api,通常用法:v-on:click="getInfo" 或者简写 @click="handleClick"。在上述案例代码中v-on后面直接就是="gridEvents"这并不是错误写法, 而是v-on的对象式事件绑定写法。和常用的 @click="handleClick" 属于同一套事件绑定机制,仅写法形式不同。
两种写法对比
1. 单个事件(常规熟悉写法)
@ 是 v-on: 的语法糖,两种写法完全等价:
<button @click="handleClick">点击</button>
<!-- 等价于 -->
<button v-on:click="handleClick">点击</button>
2. 对象式绑定(v-on="对象" 用法)
直接通过 v-on 绑定一个事件对象,适用于多个事件绑定的场景:
<vxe-grid v-on="gridEvents"></vxe-grid>
其中 gridEvents 是一个键值对对象:
- 键:事件名(如
pageChange、cellClick) - 值:该事件对应的处理函数
Vue会自动遍历这个对象,将每个键值对解析为「v-on:事件名=处理函数」的形式完成绑定。
在代码中的实际含义
以 vxe-table的分页事件为例,实际定义的事件对象如下(包含TypeScript类型约束):
const gridEvents: VxeGridListeners = {
pageChange({ pageSize, currentPage }) {
pagerVO.currentPage = currentPage
pagerVO.pageSize = pageSize
loadList()
},
}
此时 v-on="gridEvents" 完全等价于单个事件绑定的写法:
<vxe-grid v-on:pageChange="gridEvents.pageChange"></vxe-grid>
如果 gridEvents 中包含多个事件,Vue会自动完成所有事件的批量绑定,例如:
// 包含多个事件的处理对象
const gridEvents = {
pageChange: (e) => { ... },
editClosed: (e) => { ... },
cellClick: (e) => { ... },
}
等价于手动为每个事件单独绑定:
<vxe-grid
v-on:pageChange="gridEvents.pageChange"
v-on:editClosed="gridEvents.editClosed"
v-on:cellClick="gridEvents.cellClick"
></vxe-grid>
为什么使用对象式事件绑定写法?
- 事件多时更简洁:无需在模板中重复书写大量
v-on:xxx="xxx",仅需一个v-on="对象"即可完成批量绑定,简化模板代码; - 便于维护:所有事件的处理函数都集中在一个对象中,事件名和对应逻辑一一对应,后续新增 / 修改 / 删除事件时,只需操作该对象,无需改动模板;
- 适配组件库场景:
vxe-table、Element Plus这类 UI 组件库的复杂组件(如表格、树形控件)通常提供大量事件,使用对象统一配置事件,代码结构会更清晰。
以上便是对v-on的分享,欢迎大家指正讨论,与大家共勉。