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
相关产品推荐
相关产品推荐

