简单学习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 相关文章推荐
Jquery AJAX 用于计算点击率(统计)
Jun 30 Javascript
关于js datetime的那点事
Nov 15 Javascript
JavaScript实现快速排序(自已编写)
Dec 19 Javascript
Extjs4中Form的使用之本地hiddenfield
Nov 26 Javascript
jQuery实现字符串全部替换的方法【推荐】
Mar 09 Javascript
以BootStrap Tab为例写一个前端组件
Jul 25 Javascript
原生JS进行前后端同构
Apr 22 Javascript
vue引入js数字小键盘的实现代码
May 14 Javascript
解决betterScroll在vue中存在图片时,出现拉不动的问题
Sep 27 Javascript
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
Apr 01 Javascript
Webpack设置环境变量的一些误区详解
Dec 19 Javascript
Element DateTimePicker日期时间选择器的使用示例
Jul 27 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
WAR3重制版DOTA 5V5初体验
2020/04/09 DOTA
PHP中模拟处理HTTP PUT请求的例子
2014/07/22 PHP
php命令行(cli)模式下报require 加载路径错误的解决方法
2015/11/23 PHP
PHP数组函数知识汇总
2016/05/12 PHP
PHP+Apache+Mysql环境搭建教程
2016/08/01 PHP
PHPUnit + Laravel单元测试常用技能
2019/11/06 PHP
不要小看注释掉的JS 引起的安全问题
2008/12/27 Javascript
实现png图片和png背景透明(支持多浏览器)的方法
2009/09/08 Javascript
jQuery学习笔记之toArray()
2014/06/09 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
2014/08/22 Javascript
JS实现CheckBox复选框全选全不选功能
2015/05/06 Javascript
javascript无刷新评论实现方法
2015/05/13 Javascript
XMLHttpRequest Level 2 使用指南
2016/08/26 Javascript
js仿搜狐视频记录片列表展示效果
2020/05/30 Javascript
引入外部js脚本加载慢与页面白屏问题的解决
2018/12/10 Javascript
零基础之Node.js搭建API服务器的详解
2019/03/08 Javascript
js+html5 canvas实现ps钢笔抠图
2019/04/28 Javascript
利用Vue-draggable组件实现Vue项目中表格内容的拖拽排序
2019/06/07 Javascript
jQuery/JS监听input输入框值变化实例
2019/10/17 jQuery
原生JS利用transform实现banner的无限滚动示例代码
2020/06/15 Javascript
node.js通过Sequelize 连接MySQL的方法
2020/12/28 Javascript
python的常见命令注入威胁
2013/02/18 Python
通过mod_python配置运行在Apache上的Django框架
2015/07/22 Python
详解python 字符串和日期之间转换 StringAndDate
2017/05/04 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
python学生管理系统代码实现
2020/04/05 Python
python地震数据可视化详解
2019/06/18 Python
Space NK美国站:英国高端美妆护肤商城
2017/05/22 全球购物
企划专员岗位职责
2013/12/09 职场文书
村庄绿化方案
2014/05/07 职场文书
消防安全宣传口号
2014/06/10 职场文书
2014年预备党员端正入党动机思想汇报
2014/09/13 职场文书
打架检讨书范文
2015/01/27 职场文书
小学四年级作文之写景
2019/08/23 职场文书
IDEA使用SpringAssistant插件创建SpringCloud项目
2021/06/23 Java/Android
Go语言特点及基本数据类型使用详解
2022/03/21 Golang