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

Vue2转Vue3:Options API下如何拦截组件emit事件

Vue3 Options API 下拦截 $emit 日志插件改写方案

直接通过修改 app.config.globalProperties 覆盖 $emit 方法即可适配Vue3的插件机制,不需要用到defineEmits(它是Composition API的专属语法,和全局拦截需求无关)。改写后的代码如下:

function plugin(app, options = {}) {
  // 保存原始的$emit方法
  const originalEmit = app.config.globalProperties.$emit;
  // 覆盖全局$emit方法
  app.config.globalProperties.$emit = function (...args) {
    // 获取触发事件的组件标识,Vue3 Options API实例仍可访问$vnode
    const from = this.$vnode ? this.$vnode.tag : 'Event without vnode';
    // 保留原日志逻辑
    if (args.length > 1) {
      log.event(`Event "${args[0]}" from ${from}: `, ...args.slice(1));
    } else {
      log.event(`Event "${args[0]}" from ${from}`);
    }
    // 调用原始$emit方法确保事件正常触发
    originalEmit.apply(this, args);
  };
}

// 插件使用方式
// createApp(App).use(plugin).mount('#app')

关键改动说明:

  • 插件参数变更:Vue3插件的第一个参数是createApp返回的app实例,不再是Vue构造函数
  • 全局属性修改方式:Vue3废弃了直接修改Vue.prototype的做法,改用app.config.globalProperties定义全局可访问的方法/属性,Options API组件实例会自动继承这些全局属性
  • 逻辑兼容:原日志记录逻辑完全保留,仅调整了$emit的获取和覆盖方式

可选优化:

如果this.$vnode.tag在部分场景下无法给出清晰的组件标识,可以替换为this.$options.name(需要组件定义时显式声明name选项),日志可读性会更强。

内容的提问来源于stack exchange,提问作者scader

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 06:22:32