简单学习5种处理Vue.js异常的方法


Posted in Javascript onJune 17, 2019

错误大全

为了测试各种异常处理技巧,我故意触发三种类型的错误。

第一种:引用一个不能存在的变量:

<div id="app" v-cloak>
Hello, {{name}}
</div>

上述代码运行后不会抛出错误,但是在控制台会有[Vue warn]消息。

简单学习5种处理Vue.js异常的方法

你可以在Codepen查看例子完整代码。

第二种:将变量绑定到一个被计算出来的属性,计算的时候会抛出异常。

<div id="app" v-cloak>
Hello, {{name2}}
</div>
<script>
const app = new Vue({
el:'#app',
computed:{
name2() {
return x;
}
}
})
</script>

运行上述代码会在控制台抛出一个[Vue warn]和一个常规的错误,网页白屏。

简单学习5种处理Vue.js异常的方法

你可以在Codepen查看例子完整代码。

第三种:执行一个会抛出异常的方法

<div id="app" v-cloak>
<button @click="doIt">Do It</button>
</div>
<script>
const app = new Vue({
el:'#app',
methods:{
doIt() {
return x;
}
}
})
</script>

这个错误在控制台也[Vue warn]和常规报错。和上一个错误的区别在于,只有你点击了按钮才会触发函数调用,才会报错。

简单学习5种处理Vue.js异常的方法

你可以在Codepen查看例子完整代码。

在继续之前,我想声明上面3个例子并不代表所有类型的错误。这3种是比较常见的错误。

好了,我们该怎么处理异常呢?我很惊讶在Vue的文档中竟然没有介绍异常处理的章节。

简单学习5种处理Vue.js异常的方法

是的,文档中是有一个,但是介绍极其简短。

如果在组件渲染时出现运行错误,错误将会被传递至全局 Vue.config.errorHandler 配置函数 (如果已设置)。利用这个钩子函数来配合错误跟踪服务是个不错的主意。比如 Sentry,它为 Vue 提供了官方集成。

P.S. 国产BUG监控服务Fundebug也为Vue提供了官方集成。
我个人建议官方应该有详细的介绍。总的来说,Vue中异常处理包含以下几个方面的技巧:

  • errorHandler
  • warnHandler
  • renderError
  • errorCaptured
  • window.onerror (不仅仅针对Vue)

技巧1:errorHandler

我们要学习的第一个技巧是errorHandler。你也许知道,这是Vue中最广泛使用的异常处理方式。

Vue.config.errorHandler = function(err, vm, info) {
}

err指代error对象,info是一个Vue特有的字符串,vm指代Vue应用本身。记住在一个页面你可以有多个Vue应用。这个error handler作用到所有的应用。

Vue.config.errorHandler = function(err, vm, info) {
console.log(`Error: ${err.toString()}\nInfo: ${info}`);
}

第一种错误不会触发errorHandler,它只是一个warning。

第二种错误会抛出错误被errorHandler捕获:

Error: ReferenceError: x is not defined
Info: render

第三种错误也会被捕获:

Error: ReferenceError: x is not defined
Info: v-on handler

记住info里面的信息也是非常有用的。

技巧2: warnHandler

warnHandler用来捕获Vue warning。记住在生产环境是不起作用的。

Vue.config.warnHandler = function(msg, vm, trace) {
}

msg和vm都容易理解,trace代表了组件树。请看下面的例子:

Vue.config.warnHandler = function(msg, vm, trace) {
console.log(`Warn: ${msg}\nTrace: ${trace}`);
}

第一个错误被warnHandler捕获:

Warn: Property or method 'name' is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Trace:
(found in <Root>)

你可以查看三个例子的实际运行情况:

第一个: 例子1

第二个: 例子2

第三个: 例子3

技巧3: renderError

和前面两个不同,这个技巧不适用于全局,和组件相关。并且只适用于非生产环境。

下面是一个简单的例子:

const app = new Vue({
el:'#app',
renderError (h, err) {
return h('pre', { style: { color: 'red' }}, err.stack)
}
})

第一个例子是没有效果的,因为只是一个warning。第二个例子就会在网页上显示具体的错误信息: 示例代码

老实说,我没觉得这个比直接看控制台好多少。但是,如果你们的QA团队或则测试对浏览器控制台不熟悉的话,这个还是蛮有用的。

技巧4: errorCaptured

errorCaptured是最后一个和Vue相关的技巧,这个技巧让我很迷惑,现在还是有点搞不明白。文档是这么介绍的:

当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

基于我的一些分析,这个error Handler只能在父组件中处理子组件的错误。据我所知,我们没法直接在Vue的主实例(main instance)中使用它。

为了测试,我构造了下面的例子:

Vue.component('cat', {
template:`
<div><h1>Cat: </h1>
<slot></slot>
</div>`,
props:{
name:{
required:true,
type:String
}
},
errorCaptured(err,vm,info) {
console.log(`cat EC: ${err.toString()}\ninfo: ${info}`); 
return false;
}
});
Vue.component('kitten', {
template:'<div><h1>Kitten: {{ dontexist() }}</h1></div>',
props:{
name:{
required:true,
type:String
}
}
});

注意 kitten 组件的代码是有BUG的。

<div id="app" v-cloak>
<cat name="my cat">
<kitten></kitten>
</cat>
</div>

捕获的信息如下:

cat EC: TypeError: dontexist is not a function
info: render

下面是运行实例。

errorCaptured是个很有趣的特性,我想哪些构建组件库的开发者应该会用到吧。这个特性更像是一个面向组件开发者而不是一般开发者。

终极技巧: window.onerror

最后也是最重要的一个候选项 window.onerror。它是一个全局的异常处理函数,可以抓取所有的JavaScript异常。

window.onerror = function(message, source, line, column, error) {
}

我想函数的参数中只有source难以从字面上理解吧,它代表了当前的URL。

接下来事情就比较好玩了。如果你定义了onerror,但是没有启用Vue.config.errorHandler,那么有很多异常都抓不到。Vue希望你要定义它,否则异常不会抛出去的。这到底有没有意义?我不是很懂,我觉得没必要,甚至有点奇怪。

如果定义errorHandler的代码有BUG,那么运行起来也不会被onerror抓到。下面的例子中,如果将oopsIDidItAgain()解注释,你就会发现这个问题。只有第二个按钮没有和Vue绑定,所以报错无论如何都会被抓到。运行实例

总结

正如开篇提到,这是我第一次写关于这个主题的文章。我也希望从大家获得反馈,包括评论、建议以及修订意见。我希望大家可以分享自己如何使用的具体事例。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
innerHTML 和 getElementsByName 在IE下面的bug 的解决
Apr 09 Javascript
JavaScript起点(严格模式深度了解)
Jan 28 Javascript
javascript重复绑定事件造成的后果说明
Mar 02 Javascript
jquery的ajax请求全面了解
Mar 20 Javascript
js换图片效果可进行定时操作
Jun 09 Javascript
JavaScript函数详解
Nov 17 Javascript
简单实现IONIC购物车功能
Jan 10 Javascript
JavaScript标准对象_动力节点Java学院整理
Jun 27 Javascript
移动端图片上传旋转、压缩问题的方法
Oct 16 Javascript
微信小程序实现文字无限轮播效果
Dec 28 Javascript
11个教程中不常被提及的JavaScript小技巧(推荐)
Apr 17 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 Javascript
js/jQuery实现全选效果
Jun 17 #jQuery
解决微信浏览器缓存站点入口文件(IIS部署Vue项目)
Jun 17 #Javascript
通过说明与示例了解js五种设计模式
Jun 17 #Javascript
简单了解vue.js数组的常用操作
Jun 17 #Javascript
送你43道JS面试题(收藏)
Jun 17 #Javascript
通过实例学习React中事件节流防抖
Jun 17 #Javascript
如何解决js函数防抖、节流出现的问题
Jun 17 #Javascript
You might like
PHP学习之PHP变量
2006/10/09 PHP
解析CodeIgniter自定义配置文件
2013/06/18 PHP
PHP基于数组实现的分页函数实例
2014/08/20 PHP
php使用escapeshellarg时中文被过滤的解决方法
2016/07/10 PHP
php原生导出excel文件的两种方法(推荐)
2016/11/19 PHP
php实现的错误处理封装类实例
2017/06/20 PHP
一个实用的php验证码类
2017/07/06 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
JavaScript使用Prototype实现面向对象的方法
2015/04/14 Javascript
关于获取DIV内部内容报错的原因分析及解决办法
2016/01/29 Javascript
JQuery之proxy实现绑定代理方法
2016/08/01 Javascript
JS模拟实现ECMAScript5新增的数组方法
2017/03/20 Javascript
Vue.js手风琴菜单组件开发实例
2017/05/16 Javascript
原生js实现简单的模态框示例
2017/09/08 Javascript
Angular实现点击按钮后在上方显示输入内容的方法
2017/12/27 Javascript
vue+webpack实现异步组件加载的方法
2018/02/03 Javascript
angular6的table组件开发的实现示例
2018/12/26 Javascript
小程序点击图片实现png转jpg
2019/10/22 Javascript
十分钟教你上手ES2020新特性
2020/02/12 Javascript
Vue-cli assets SubDirectory及PublicPath区别详解
2020/08/18 Javascript
[17:13]DOTA2 HEROS教学视频教你分分钟做大人-斯拉克
2014/06/13 DOTA
python连接mysql数据库示例(做增删改操作)
2013/12/31 Python
python自定义类并使用的方法
2015/05/07 Python
python学习--使用QQ邮箱发送邮件代码实例
2019/04/16 Python
python 利用turtle库绘制笑脸和哭脸的例子
2019/11/23 Python
canvas实现飞机打怪兽射击小游戏的示例代码
2018/07/09 HTML / CSS
一些常用的HTML5模式(pattern) 总结
2015/07/14 HTML / CSS
德国排名第一的主题公园门票网站:Attraction Tickets Direct
2019/09/09 全球购物
国际贸易专业推荐信
2013/11/15 职场文书
春节联欢会策划方案
2014/05/16 职场文书
银行贷款委托书范本
2014/10/11 职场文书
2014三年级班主任工作总结
2014/12/05 职场文书
2016大学自主招生推荐信范文
2015/03/23 职场文书
2015年数学教研组工作总结
2015/05/23 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
vue特效之翻牌动画
2022/04/20 Vue.js