Mitt事件总线Vue组件内可用 axios拦截器中调用报undefined
问题原因
组件中this.emitter可正常调用,是因为Vue框架会自动将app.config.globalProperties挂载的属性代理到组件实例的this上下文,这种访问方式仅在Vue组件内部的执行上下文生效。
你的axios拦截器写在独立的普通JS模块client.js中,不属于Vue组件的执行上下文,这里的this不会指向Vue组件实例(ES模块严格模式下this值为undefined),访问this.emitter自然会触发undefined报错。
解决方法
不要依赖Vue实例的this上下文获取事件总线,直接复用独立的mitt实例即可,这也是mitt这类独立工具库的推荐使用方式:
- 单独抽离并导出mitt实例,避免和Vue实例强绑定
新建src/utils/emitter.js:
import mitt from 'mitt' const emitter = mitt() export default emitter
- 调整main.js逻辑,引入上述导出的emitter实例挂载到全局,保证原有组件内的
this.emitter写法可以正常使用,不需要修改已有组件代码:
import { createApp } from 'vue' import App from './App.vue' import emitter from './utils/emitter' const app = createApp(App) app.config.globalProperties.emitter = emitter app.mount('#app')
- 修改axios实例文件
client.js,直接引入emitter实例调用,不再通过this访问:
import axios from 'axios' import emitter from './utils/emitter' const client = axios.create({ baseURL: authenticated.data.domain ?? 'http://mydomain.test/api' }); client.interceptors.response.use((response) => { emitter.emit('alert', response.data); return response; }, (error) => { return Promise.reject(error.message); }); export default client;
这种方案下事件总线实例完全独立,无论是Vue组件、普通工具函数、axios拦截器还是其他业务模块,都可以直接引入实例使用,不会被this上下文绑定问题限制,耦合度更低。
内容的提问来源于stack exchange,提问作者user19252998
相关产品推荐
相关产品推荐

