持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
如何统一监听Vue组件报错?
我们实际工作中,可以把项目完成、上线,仅仅使我们开发最基础的一环,也是最开始的一步。
项目需要闭环,即考虑各个方面,除了基本的功能外,还要考虑性能优化、报错、统计等。
那么,监控错误这是我们在实际工作中很重要的一点,它可以保证我们在开发中及早的发现问题,并解决掉,也可以在生产问题的排查上发挥至关重要的作用
那么如何统一监听 Vue 组件报错?
1. GlobalEventHandlers.onerror【1】
- 它是全局监听所有 JavaScript 错误
- 当JavaScript 运行时错误(包括语法错误)发生时,window会触发一个ErrorEvent接口的error事件,并执行window.onerror()。
- 但是!他是 JavaScript 级别的,识别不了 Vue 组件信息
- Vue本身也是编译成js运行(万变不离其宗嘛!), window.onerror 也是可以监听到报错的
- Vue 经过压缩打包之后,window.onerror 识别不了 Vue 组件信息,虽然可以监听到错误,但是没有那么容易进行错误定位
注意,全局只绑定一次即可。不要放在多次渲染的组件中,这样容易绑定多次。
使用
由于历史原因,
window.onerror
和element.onerror
接受不同的参数。
onerror:
window.onerror = function(message, source, lineno, colno, error) { ... }
addEventListener:
window.addEventListener('error', function(event) { ... })
errorCaptured(vue的生命周期钩子函数)【2】
如果我问你生命周期,你肯定会掰着手指头和我说:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
- activated
- deactivated
但是我和你说 还有个这个 errorCaptured,说不定你就一脸懵逼了
官方文档说明
2.5.0+ 新增
- 类型:
(err: Error, vm: Component, info: string) => ?boolean
- 详细: 在捕获一个来自后代组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回
false
以阻止该错误继续向上传播。
使用
<template>
<div id="nav">
...
</div>
</template>
<script>
export default {
mounted() {
...
},
errorCaptured: (err, vm, info) => {
console.info('errorCaptured----', err, vm, info)
// return false
},
}
</script>
errorHandler【3】
指定组件的渲染和观察期间未捕获错误的处理函数。这个处理函数被调用时,可获取错误信息和 Vue 实例。
PS:值得一提的是
errorCaptured
返回false
则不会到这里。
使用
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.config.errorHandler = (error, vm, info) => {
console.info('errorHandler----', error, vm, info)
}
app.use(router).mount('#app')
总结
errorCaptured
监听下级组件的错误,可返回false
阻止向上传播errorHandler
监听 Vue 全局错误window.onerror
监听其他的 JS 错误,如异步
建议:结合使用
- 一些重要的、复杂的、有运行风险的组件,可使用
errorCaptured
重点监听 - 然后用
errorHandler
window.onerror
候补全局监听,避免意外情况
文档
【1】GlobalEventHandlers.onerror 【2】errorCaptured 【3】errorHandler