查看: 2647|回复: 3

Vue @change事件传参与$event取值及无参调用区别

[复制链接]
发表于 前天 13:00 | 显示全部楼层 |阅读模式
在Vue组件开发中,@change常用于监听表单控件或开关组件的状态变化。本文围绕一个switch组件的@change用法展开,说明如何通过事件对象取值、如何不传组件事件只执行其它操作,以及如何同时传递事件对象和自定义参数。原文代码基于Options API写法。

一、通过@change获取组件信息
模板中可以写成 @change="handleIsUsedChange" 或 @change="handleIsUsedChange($event)"。两者都会把组件change事件对象传给处理函数。处理函数接收到的val中,可通过 val.detail.value 取得当前值,原文取值为 true 或 false。示例:
  1. <template>
  2.   <switch
  3.     :checked="isUsed"
  4.     @change="handleIsUsedChange"
  5.     color="#1890FF"
  6.   />
  7. </template>
  8. <script>
  9. export default {
  10.   data() {
  11.     return {
  12.       isUsed: 'true'
  13.     }
  14.   },
  15.   methods: {
  16.     handleIsUsedChange(val) {
  17.       this.isUsed = val.detail.value // true or false
  18.     }
  19.   }
  20. }
  21. </script>
复制代码

也可以写成:
  1. @change="handleIsUsedChange($event)"
复制代码
处理函数仍为 handleIsUsedChange(val),val.detail.value 表示开关当前值。color="#1890FF" 用于修改switch颜色。这里要注意:如果直接写方法名,Vue会默认传入事件对象;如果写成 handleIsUsedChange($event),则是显式传入事件对象。

二、不传递组件信息,只执行其它操作
如果@change中写成 handleIsUsedChange(),则不会把组件事件对象传给方法。此时方法形参val取不到值,结果为 undefined。这种写法适合只希望在change触发时执行额外操作,而不需要读取组件当前值的场景。示例:
  1. <template>
  2.   <switch
  3.     :checked="isUsed"
  4.     @change="handleIsUsedChange()"
  5.     color="#1890FF"
  6.   />
  7. </template>
  8. <script>
  9. export default {
  10.   data() {
  11.     return {
  12.       isUsed: 'true'
  13.     }
  14.   },
  15.   methods: {
  16.     handleIsUsedChange(val) {
  17.       // val 取到的值 undefined
  18.       // 这里可以执行其它操作
  19.     }
  20.   }
  21. }
  22. </script>
复制代码

三、同时传递组件信息和自定义参数
当既需要拿到change事件对象,又需要传入普通参数时,需要显式传入 $event,并继续追加参数。例如:
  1. <template>
  2.   <switch
  3.     :checked="isUsed"
  4.     @change="handleIsUsedChange($event, '参数')"
  5.     color="#1890FF"
  6.   />
  7. </template>
  8. <script>
  9. export default {
  10.   data() {
  11.     return {
  12.       isUsed: 'true'
  13.     }
  14.   },
  15.   methods: {
  16.     handleIsUsedChange(val, param) {
  17.       // val.detail.value => true or false
  18.       // param => '参数'
  19.       this.isUsed = val.detail.value
  20.     }
  21.   }
  22. }
  23. </script>
复制代码
其中 val.detail.value 是组件的当前值,param 是自定义参数。这样可以在处理开关状态变化的同时,把额外上下文传给同一个方法。

四、用法差异与排查思路
1. @change="handleIsUsedChange" 和 @change="handleIsUsedChange($event)":都能在方法中拿到事件对象,val.detail.value 可用于取值。
2. @change="handleIsUsedChange()":方法中的val为undefined。如果发现处理函数里读不到detail.value,先检查模板中是否带了括号且没有传$event。
3. 需要“事件对象 + 自定义参数”时,必须写 @change="handleIsUsedChange($event, '参数')",不能只写方法名,也不能漏掉$event。
4. 如果只是改变switch颜色,使用color="#1890FF"即可;如果要在change时同步状态,则按上述方式把 val.detail.value 赋给组件状态。

总结:Vue中@change的写法会直接影响处理函数收到的参数。只写方法名或显式传$event,可以获取组件事件对象并读取 detail.value;写成空括号调用,则只会执行函数逻辑,形参为 undefined;若还要追加业务参数,则需要显式传入 $event 和自定义参数。
回复

使用道具 举报

发表于 前天 19:00 | 显示全部楼层

Re: Vue @change事件传参与$event取值及无参调用区别

写得很清楚,尤其是把 @change 的几种写法放在一起对比,排查时很实用。只写方法名和写 ($event) 都能拿到事件对象,通过 val.detail.value 取值;写成空括号调用则形参是 undefined,只适合执行额外操作,这个区别确实容易忽略。 需要同时传事件对象和自定义参数时,必须显式写 $event 再追加参数,这个点也讲得很明白。整体看下来,从取值、无参调用到混合传参的用法都覆盖到了,收藏学习。
回复 支持 反对

使用道具 举报

发表于 前天 19:10 | 显示全部楼层

Re: Vue @change事件传参与$event取值及无参调用区别

这篇整理挺清楚的,尤其是把三种写法拆开对比。实际写的时候最容易忽略的就是 @change="handleIsUsedChange()" 这种空括号调用,看着像正常调用方法,但事件对象不会自动传进去,处理函数里的 val 自然就是 undefined。需要同时拿事件对象和自定义参数时,必须显式写 $event,再追加参数,这一点很关键。按这个思路排查读不到 detail.value 的问题会快很多,感谢分享。
回复 支持 反对

使用道具 举报

发表于 前天 19:20 | 显示全部楼层

Re: Vue @change事件传参与$event取值及无参调用区别

这篇整理得挺清楚的,尤其是 @change 写方法名、显式写 $event、和写空括号这三种情况的区别,确实是实际开发里很容易搞混的点。我之前也踩过空括号导致 val 为 undefined 的坑,排查时确实要先看模板里有没有漏掉 $event。你举的 switch 例子也很直观,val.detail.value 拿到 true 或 false 后再赋给 isUsed,思路很顺;需要同时传自定义参数时,也必须显式带上 $event 才能拿到事件对象。感谢分享,后面遇到类似表单或开关组件的 change 处理可以直接对照着检查了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-12 12:30 , Processed in 0.022201 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部