You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js绑定自定义事件加括号调用方法报错原因

Vue自定义事件绑定加括号报错的原因

两种事件绑定写法的运行逻辑有本质区别,和是不是原生DOM事件没有关系:

  • 写@toggle-favorite="toggleFavorite"时,Vue会直接把toggleFavorite函数本身注册为事件回调。子组件触发事件时,Vue会自动把$emit携带的所有参数按顺序传入这个回调。你在子组件里写了this.$emit("toggle-favorite", this.id),id会被自动传给父组件的方法,逻辑可以正常执行。
    对应的子组件触发事件代码:
    toggleFavorite: function () {
      this.$emit("toggle-favorite", this.id);
    }
    
    父组件对应接收参数的方法:
    toggleFavorite: function (id) {
      let friendToUpdate = this.friends.find((el) => el.id === id);
      friendToUpdate.favorite = !friendToUpdate.favorite;
    }
    
  • 写@toggle-favorite="toggleFavorite()"时,Vue不会把函数本身注册为回调,而是把括号包裹的整段函数调用语句作为内联脚本,事件触发时直接执行这段脚本。你括号里没有传任何参数,相当于执行了无参的toggleFavorite(),方法里接收到的id是undefined,后续执行find查找时拿undefined和好友id做匹配,根本找不到对应元素,返回的friendToUpdate值为undefined,再访问friendToUpdate.favorite自然就会抛出类型错误。
    你之前觉得原生@click事件两种写法都能跑,本质是之前写点击事件时要么没用到事件参数,要么手动传了需要的参数——如果写@click="handleClick()"又没手动传$event占位符,方法里同样拿不到原生事件对象,只是之前没用到这个对象所以没触发报错而已。

带括号的正确写法

如果习惯写带括号的调用形式,需要手动用Vue内置的$event占位符接住子组件抛出的参数,再传入方法:

<friend-contact
  v-for="friend in friends"
  :data="friend"
  :key="friend.id"
  @toggle-favorite="toggleFavorite($event)"
>
</friend-contact>

这里的$event就对应子组件$emit时传入的第一个参数(也就是你传的id),手动传入后方法就能正常拿到值运行。如果子组件$emit携带了多个参数,后续参数可以通过arguments[1]、arguments[2]的形式依次获取,日常开发只需要接收单个参数时,直接写方法名不加括号是最简便的写法。


内容的提问来源于stack exchange,提问作者shoko-moko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:45:35