详解Vue 的异常处理机制

最近需要在业务中加一个全局的 filter,filter 会对输入进行验证,用于进行前端监控。其中一个要处理的问题,就是验证失败后如何发送异常日志,这个过程中顺便了解了一下 vue 的异常处理机制。

errorCaptured、errorHandler

vue 提供了两个 API 用于异常的捕获,分别是 errorCapturederrorHandler

  1. errorCaptured

errorCaptured 是组件的一个钩子函数,用于在组件级别捕获异常。当这个钩子函数返回 false 时,会阻止异常进一步向上冒泡,否则会不断向父组件传递,直到 root 组件。

  1. errorHandler

errorHandler 是一个全局的配置项,用来在全局捕获异常。例如Vue.config.errorHandler = function (err, vm, info) {}。

error.js

在 vue 源码中,异常处理的逻辑放在 /src/core/util/error.js 中:

import config from '../config'
import { warn } from './debug'
import { inBrowser } from './env'

export function handleError (err: Error, vm: any, info: string) {
 if (vm) {
  let cur = vm
  while ((cur = cur.$parent)) {
   const hooks = cur.$options.errorCaptured
   if (hooks) {
    for (let i = 0; i < hooks.length; i++) {
     try {
      const capture = hooks[i].call(cur, err, vm, info) === false
      if (capture) return
     } catch (e) {
      globalHandleError(e, cur, 'errorCaptured hook')
     }
    }
   }
  }
 }
 globalHandleError(err, vm, info)
}

function globalHandleError (err, vm, info) {
 if (config.errorHandler) {
  try {
   return config.errorHandler.call(null, err, vm, info)
  } catch (e) {
   logError(e, null, 'config.errorHandler')
  }
 }
 logError(err, vm, info)
}

function logError (err, vm, info) {
 if (process.env.NODE_ENV !== 'production') {
  warn(`Error in ${info}: "${err.toString()}"`, vm)
 }
 /* istanbul ignore else */
 if (inBrowser && typeof console !== 'undefined') {
  console.error(err)
 } else {
  throw err
 }
}

文件不长,向外暴露了一个 handleError 方法,在需要捕获异常的地方调用。handleError 方法中首先获取到报错的组件,之后递归查找当前组件的父组件,依次调用 errorCaptured 方法。在遍历调用完所有 errorCaptured 方法、或 errorCaptured 方法有报错时,会调用 globalHandleError 方法。

globalHandleError 方法调用了全局的 errorHandler 方法。

如果 errorHandler 方法自己又报错了呢?生产环境下会使用 console.error 在控制台中输出。

可以看到 errorCaptured 和 errorHandler 的触发时机都是相同的,不同的是 errorCaptured 发生在前,且如果某个组件的 errorCaptured 方法返回了 false,那么这个异常信息不会再向上冒泡也不会再调用 errorHandler 方法。

以上就是详解Vue 的异常处理机制的详细内容,更多关于vue 异常处理的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue之父子组件间通信实例讲解(props、$ref、$emit)

    组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.那么组件间如何通信,也就成为了vue中重点知识了.这篇文章将会通过props.$ref和 $emit 这几个知识点,来讲解如何实现父子组件间通信. 在说如何实现通信之前,我们先来建两个组件father.vue和child.vue作为示例的基础. //父组件 <template> <div> <h1>我是父组件!</h1> <child>

  • 优雅的处理vue项目异常实战记录

    背景 你还在为处理Uncaught (in promise) ReferenceError烦恼吗? 你还在为捕获异常反复的写try catch吗? 你还在为每一个promise写catch吗? 是时候一站式统一处理异常!!!(针对vue项目) 全局异常捕获 Vue.config.errorHandler = function (err, vm, info) { // 指定组件的渲染和观察期间未捕获错误的处理函数.这个处理函数被调用时,可获取错误信息和 Vue 实例. // handle erro

  • vue引用js文件的多种方式(推荐)

    1.vue-cli webpack全局引入jquery (1) 首先 npm install jquery --save (--save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖.) (2)在webpack.base.conf.js里加入 var webpack = require("webpack") (3)在module.exports的最后加入 plugins: [ new webpack.optimize.CommonsChu

  • Vue props用法详解(小结)

    Vue props用法详解 组件接受的选项之一 props 是 Vue 中非常重要的一个选项.父子组件的关系可以总结为: props down, events up 父组件通过 props 向下传递数据给子组件:子组件通过 events 给父组件发送消息. 父子级组件 比如我们需要创建两个组件 parent 和 child.需要保证每个组件可以在相对隔离的环境中书写,这样也能提高组件的可维护性. 这里我们先定义父子两个组件和一个 Vue 对象: var childNode = { templat

  • Vue.js常用指令汇总(v-if、v-for等)

    有时候指令太多会造成记错.记混的问题,所以本文在记忆的时候会采用穿插记忆的方式,交叉比对,不易出错. 本文主要讲了一下六个指令: v-if//v-show//v-else//v-for//v-bind//v-on 1. v-if 条件渲染指令,根据其后表达式的bool值进行判断是否渲染该元素: eg: HTML: <div id="example01"> <p v-if="male">Male</p> <p v-if=&qu

  • vue实现文件上传功能

    vue 文件上传,供大家参考,具体内容如下 首先 先说一下想要实现的效果 就如截图所见,需要将企业和需要上传的文件提交到后台处理,那么接下来就说如何实现 vue 实现 vue 页面代码 <el-upload class="upload-demo" ref="upload" action="doUpload" :limit="1" :file-list="fileList" :before-upload

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

    错误大全 为了测试各种异常处理技巧,我故意触发三种类型的错误. 第一种:引用一个不能存在的变量: <div id="app" v-cloak> Hello, {{name}} </div> 上述代码运行后不会抛出错误,但是在控制台会有[Vue warn]消息. 111111111111111111 你可以在Codepen查看例子完整代码. 第二种:将变量绑定到一个被计算出来的属性,计算的时候会抛出异常. <div id="app" v-

  • vue项目刷新当前页面的三种方法

    想必大家在刨坑vue的时候也遇到过下面情形:比如在删除或者增加一条记录的时候希望当前页面可以重新刷新或者如下面这种: 如果希望点击确定的时候,Dialog 对话框关闭的时候,当前http://localhost:9530/#/supplier/supplierAll页面可以重新刷新下 那么表格的数据可以重新加载,Dialog 对话框设置的数据可以在确定后刷新出现在页面上 这时候我们最直接的思维就是想到下面这种: 但是,试过的会发现用vue-router重新路由到当前页面,页面是不进行刷新的,根本

  • vue 表单输入格式化中文输入法异常问题

    v-model 是 vue.js 提供的语法糖,根据不同的表单控件监听不同的事件,实现对表单控件的数据双向绑定. 当控件是 <input> 输入框时,v-model 监听其 input 事件. 如下所示,这两种写法有什么区别吗? <input :value="name" @input="name = $event.target.value"><input v-model="name"> 输入中文格式化问题 表单

  • Vue.js实战之利用vue-router实现跳转页面

    前言 使用 Vue.js 做项目的时候,一个页面是由多个组件构成的,所以在跳转页面的时候,并不适合用传统的 href,于是 vue-router 应运而生. 官方文档: https://router.vuejs.org/zh-cn/essentials/getting-started.html 这次的实例主要实现下图的效果: 项目结构: 一.配置 Router 用 vue-cli 创建的初始模板里面,并没有 vue-router,需要通过 npm 安装 cnpm i vue-router -D

  • vue 项目build错误异常的解决方法

    在生成vue项目的时候,出现如下错误 ERROR in static/js/index.d66d806fcdd72b36147b.js from UglifyJs Unexpected token: punc (() [src/components/Hello.vue:26,0][static/js/index.d66d806fcdd72b36147b.js:34,6] ERROR in static/js/cell.89bb6f1195b769a2c949.js from UglifyJs U

随机推荐