Vue.js下拉框触发onChange事件时出现beforeDestroy钩子TypeError
实现场景
- 技术栈为 Vue.js + Inertia.js
- 页面内实现下拉选择组件,通过
v-model绑定变量grade,@change事件绑定方法onChange onChange方法内的核心逻辑:选中值变化时,通过this.$inertia.get('training?gradeId='+this.grade)发起路由页面请求
异常表现
每次从下拉框选中选项、触发change事件时,控制台抛出如下错误:Error in beforeDestroy hook: "TypeError: function () { src_instanceMap.delete(instance.__VUE_DEVTOOLS_UID__) } is not a function"
报错根因
该报错并非业务逻辑错误,核心触发链路为:
- 报错栈中出现的
src_instanceMap、__VUE_DEVTOOLS_UID__均为 Vue Devtools 在开发环境下注入的调试依赖,本身不属于项目业务代码的运行逻辑 - 当前项目的 Vue 版本、Inertia Vue 适配器版本,与安装的
@vue/devtools-api版本存在兼容问题:当Inertia发起页面请求、销毁旧组件实例时,绑定在组件beforeDestroy钩子里的Devtools实例清理方法,已经丢失了对原生Map对象的引用,执行delete操作时就会抛出“不是函数”的类型错误 - 下拉框触发Inertia路由跳转的操作,刚好触发了组件销毁流程,将这个被版本兼容问题隐藏的异常暴露出来
处理方案
- 第一步:定位验证
临时关闭浏览器的Vue Devtools扩展,刷新页面后重复触发下拉选择操作,如果报错消失,即可确认异常来源为Devtools兼容问题,不影响核心业务逻辑 - 第二步:优化Inertia请求配置
调整onChange方法内的请求参数,避免不必要的组件全量销毁重建:
通过onChange() { this.$inertia.get(`training?gradeId=${this.grade}`, {}, { preserveState: true, preserveScroll: true }) }preserveState配置让Inertia在更新路由数据时保留当前组件实例,不触发销毁钩子,从流程上绕开兼容类的异常触发点 - 第三步:对齐依赖版本
检查项目内安装的@vue/devtools-api版本,针对Vue2项目固定为6.5.0兼容版本,避免高版本Devtools API对旧实例的清理逻辑不匹配Vue2的组件生命周期执行流程 - 第四步:生产环境验证
执行生产构建后访问部署页面,生产环境不会注入Devtools相关的调试逻辑,该类报错本身就不会在生产环境出现,不会影响线上用户的使用体验
内容的提问来源于stack exchange,提问作者Vicky Nehare
相关产品推荐
相关产品推荐

