封装自定义组件时如何正确传递事件监听器?

程序员美蓝 阅读 50

我最近在封装一个按钮组件,想让父组件能监听点击事件,但试了几次都没成功。我在子组件里用 $emit 触发事件,父组件用 @click 监听,结果完全没反应。

是不是我写法有问题?下面是我的子组件代码:

export default {
  name: 'MyButton',
  methods: {
    handleClick() {
      this.$emit('click', 'custom data');
    }
  }
}
我来解答 赞 11 收藏
二维码
手机扫码查看
2 条解答
シ永臣
シ永臣 Lv1
封装自定义组件时,确实要用 $emit 来触发事件,但父组件监听的方式有些问题。你在父组件里用了 @click,这样会覆盖子组件的点击事件处理逻辑。正确的做法是在父组件里直接监听子组件触发的自定义事件。

你可以这样改一下:

子组件代码保持不变,父组件这样写:

template: 



,
methods: {
handleButtonClick(data) {
console.log('Button clicked with data:', data);
}
}


这里的关键是,父组件监听的是子组件通过 $emit 触发的 'click' 事件,而不是原生的 DOM click 事件。所以模板里的 @click 实际上是 @click.native 在 Vue 2 中,或者直接 @click 在 Vue 3 中,用于监听子组件的自定义事件。

如果是在 Vue 3 中,并且 MyButton 是一个组合式 API 组件,确保你正确地 emit 事件,然后父组件这样监听:

template: 



,
methods: {
handleButtonClick(data) {
console.log('Button clicked with data:', data);
}
}


这样应该就能正常工作了。常见的解决方案就是注意事件名称和监听方式,确保两者匹配。
点赞
2026-03-23 15:18
西门逸轩
啊这个问题我遇到过!你的子组件代码其实没啥问题,但父组件那边可能写法不对。我来告诉你我是怎么做的:

在子组件里你已经正确使用了 $emit 来触发事件,很棒。关键是父组件那边绑定监听器的方式要注意。不能直接用 @click,得明确监听你自定义的事件名。

父组件应该这样写:



或者如果你的模板里已经绑定了原生点击事件:



记得检查下你的父组件有没有定义 handleButtonClick 方法哦!有时候我们以为事件没触发,其实是回调函数没定义(别问我怎么知道的,我在这坑里躺过半小时...)

另外如果你想让点击事件冒泡,可能还需要加上 .native 修饰符,不过现在Vue3已经不推荐这么用了。
点赞
2026-03-08 16:02