Vue3实战:使用 errorHandler 捕获全局错误

你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。

在 Vue3 中,app.config.errorHandler 是一个错误处理器,用于为应用内抛出的未捕获错误指定一个全局处理函数,它接收三个参数:错误对象、触发该错误的组件实例和一个指出错误来源类型信息的字符串。

app.config.errorHandler = (err, instance, info) => {// 处理错误,例如:报告给一个服务
}

一、错误来源

它可以从下面这些来源中捕获错误:

  • 组件渲染器
  • 事件处理器
  • 生命周期钩子
  • setup() 函数
  • 侦听器
  • 自定义指令钩子
  • 过渡 (Transition) 钩子

二、错误捕获

1.启用 errorHandler,接收返回的参数,调用接口。

main.js

import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'const app = createApp(App)app.config.errorHandler = (error, instance, info) => {axios.post('/api/error', {message: error.message,type: info}).then(() => {console.log('success')})
}app.mount('#app')

第一个参数 error 是一个错误对象,包含错误的详细信息,error.message 则是一个简短的错误描述,向后台提交错误信息时 error.message 更适合。instance 组件实例,一般用不到。

2.安装 axios,并设置接口代理。

vite.config.js

import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}},server: {proxy: {'/api': {target: 'http://localhost:3000',changeOrigin: true}}}
})

3.启动一个后台服务,以 Node.js 的 Express 为例

npm init -y
npm install express

创建 index.js,并输入以下内容:


const express = require('express')
const fs = require('fs')
const app = express()
app.use(express.json())app.post('/api/error', (req, res) => {const { message, type } = req.bodyfs.appendFile('./error.txt', `${message} - ${type} \n`, (error, data) => {if (error) {console.log(error)return}res.send({code: 8200,success: true})})
})app.listen(3000, () => {console.log('Server started on port 3000')
})

启动服务,控制台执行 node index.js,这样后台服务就启动好了。

4.当页面有报错并调用后台接口会,就会往后台的 error.txt 文件中插入一条数据。

count.value.split is not a function - transition hook 
count.value.split is not a function - transition hook 
fn is not defined - watcher callback 
fn is not defined - watcher callback 
abc is not defined - setup function 
abc is not defined - setup function 
abc is not defined - setup function 
abc is not defined - setup function 
count.value.split is not a function - mounted hook 
count.value.split is not a function - setup function 
abc is not defined - setup function 
count.value.split is not a function - setup function 
count.value.split is not a function - mounted hook 
count.value.split is not a function - mounted hook 
count.value.split is not a function - setup function 
count.value.split is not a function - mounted hook 
count.value.split is not a function - setup function 

三、示例

1.组件渲染器错误

<script setup>
import { ref } from 'vue'
const count = ref(100)
</script><template><div><!-- render function --><p>{{ count.split('') }}</p></div>
</template>

因为 count 是数字,并不具有 split 方法,所有组件渲染会报错,app.config.errorHandler 中的 info 参数的返回结果为 render function

2.事件处理器错误

指在组件的事件处理方法中产生的错误,app.config.errorHandler 中的 info 参数的返回结果为 native event handler

<script setup>
import { ref } from 'vue'const count = ref(100)function handleClick() {// count.value.split('') // 不存在的属性// fn() // 不存在的方法// console.log(abc) // 不存在的变量// throw new Error('报错了') // 主动抛出的错误
}
</script><template><div><p>{{ count }}</p><button @click="handleClick">点击</button></div>
</template>

3.生命周期钩子

指在生命周期钩子中产生的错误,app.config.errorHandler 中的 info 参数的返回结果为钩子名+ hook,如 mounted hook

<script setup>
import { ref, onMounted } from 'vue'const count = ref(100)onMounted(() => {// count.value.split('') // 不存在的属性// fn() // 不存在的方法// console.log(abc) // 不存在的变量// throw new Error('报错了') // 主动抛出的错误
})
</script><template><div><p>{{ count }}</p></div>
</template>

4.setup 函数

指在 <script setup>setup()中产生的错误,app.config.errorHandler 中的 info 参数的返回结果为 setup function

<script setup>

<script setup>
import { ref, onMounted } from 'vue'const count = ref(100)// count.value.split('') // 不存在的属性
// fn() // 不存在的方法
// console.log(abc) // 不存在的变量
// throw new Error('报错了') // 主动抛出的错误// 监听不存在的 abc,这里也是 setup 错误
watch(abc, (newValue) => {console.log(newValue)
})
</script><template><div><p>{{ count }}</p></div>
</template>

setup()

<template><div><p>{{ count }}</p></div>
</template><script>import { ref } from 'vue'export default {setup() {const count = ref(100)count.value.split('')// fn()// console.log(abc)// throw new Error('报错了')}}
</script>

5.侦听器错误

指在 watchwatchEffect 回调中产生的错误,初始化监听产生的错误属于 setup function错误,app.config.errorHandler 中的 info 参数的返回结果为 watcher callback

watch

<script setup>
import { ref, watch } from 'vue'const count = ref(100)watch(count, (newValue) => {// count.value.split('')// fn()// console.log(abc)// throw new Error('报错了')
})
</script><template><div><p>{{ count }}</p></div>
</template>

watchEffect

<script setup>
import { ref, watchEffect } from 'vue'const count = ref(100)watchEffect(() => {// count.value.split('')// fn()// console.log(abc)// throw new Error('报错了')
})
</script><template><div><p>{{ count }}</p></div>
</template>

6.自定义指令钩子错误

指在自定义指令钩子中产生的错误,app.config.errorHandler 中的 info 参数的返回结果为 directive hook

<script setup>
// 添加不存在的属性,不会导致报错
const vColor = {abc: 'abc', // 不会报错mounted: el => {el.style.color = 'red'// count.value.split('')// fn()// console.log(abc)// throw new Error('报错了')}
}</script><template><div><p v-color>hello</p></div>
</template>

7.过渡 (Transition) 钩子错误

在使用 Transition 的钩子时产生的错误,app.config.errorHandler 中的 info 参数的返回结果为 transition hook

以 onEnter 为例:

<script setup>
import { ref } from 'vue'const count = ref(100)
const show = ref(false)function handleClick() {show.value = !show.value
}function onEnter(el, done) {el.style.color = 'blue'done()// count.value.split('')// fn()// console.log(abc)// throw new Error('报错了')
}
</script><template><div><button @click="handleClick">点击</button><Transition @enter="onEnter"><p v-if="show">内容</p></Transition></div>
</template>

四、errorCaptured / onErrorCaptured()

两者作用相同,errorCaptured用于选项式API,onErrorCaptured() 用于组合式API,都为组件中的一个钩子,作用是在捕获了后代组件传递的错误时调用。

错误传递规则

  • 如果组件的继承链或组件链上存在多个 errorCaptured 钩子,对于同一个错误,这些钩子会被按从底至上的顺序一一调用。这个过程被称为“向上传递”,类似于原生 DOM 事件的冒泡机制。
  • 如果 errorCaptured 钩子本身抛出了一个错误,那么这个错误和原来捕获到的错误都将被发送到 app.config.errorHandler
  • errorCaptured 钩子可以通过返回 false 来阻止错误继续向上传递。即表示“这个错误已经被处理了,应当被忽略”,它将阻止其他的 errorCaptured 钩子或 app.config.errorHandler 因这个错误而被调用。

1.向上传递

main.js 中 app.config.errorHandler 方法不变。

Parent.vue

<script setup>
import { onErrorCaptured } from 'vue'
import Child from './Child.vue'onErrorCaptured((error, instance, info) => {console.log('from Child', error, instance, info)
})
</script><template><Child></Child>
</template>

Child.vue

<script setup>
import { onErrorCaptured } from 'vue'
import GrandChild from './GrandChild.vue'onErrorCaptured((error, instance, info) => {console.log('from GrandChild', error, instance, info)
})
</script><template><GrandChild></GrandChild>
</template>

GrandChild.vue

<script setup>
console.log(abc)// 这里不会起作用,因为 onErrorCaptured 监听来自后代组件的错误
onErrorCaptured((error, instance, info) => {console.log('from GrandChild', error, instance, info)
})
</script><template><p>hello world</p>
</template>

以上代码执行后,会以此触发 Child.vue 和 Parent.vue 中的 onErrorCaptured钩子,最后触发 app.config.errorHandler 中的回调。

2.阻止传递

如果在 Child.vue 的 onErrorCaptured 中添加 return false,那么Parent.vue 和 app.config.errorHandler 中将不会收到错误,因为 Child.vue 组织了错误的传递。

3.抛出错误

如果 Child.vue 组件的onErrorCaptured钩子中抛出了错误,那么来自 GrandChild.vue 和 Child.vue 自身的错误都会向上传递,这意味着 Parent.vue 和 app.config.errorHandler 都会收到这两个错误。

Child.vue

<script setup>
import { onErrorCaptured } from 'vue'
import GrandChild from './GrandChild.vue'onErrorCaptured((error, instance, info) => {console.log(def)// console.log('from GrandChild', error, instance, info)// return false
})
</script><template><GrandChild></GrandChild>
</template>


好了,分享结束,谢谢点赞,下期再见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144758.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

什么品牌超声波清洗机质量好?四大绝佳超声波清洗机品牌推荐!

在快节奏的现代生活中&#xff0c;个人物品的清洁卫生显得至关重要。眼镜、珠宝饰品、手表乃至日常餐厨用具&#xff0c;这些频繁接触的物品极易累积污渍与细菌。拿眼镜为例&#xff0c;缺乏定期清洁会让油渍与尘埃积累&#xff0c;进而成为细菌的温床&#xff0c;靠近眼睛使用…

人脸识别系统+电插锁安装配置过程

一、适用场景 1、各住宅小区内&#xff0c;一个单元涉及多户&#xff0c;一楼安装公共的人脸识别门禁进行身份的认证。 2、某企业的职工住宅区&#xff0c;企业统一安装人脸识别门禁认证身份。 3、自建楼栋&#xff0c;分多间出租给住户时&#xff0c;每个住户配备电子钥匙存在…

GEE使用require函数调用自己的Js库

新建了一个repository&#xff0c;名为Lib 把我的地形校正的函数放了进去 在自己的代码中调用就用到这个路径&#xff0c;主要Lib后面用冒号

观《中国数据库前世今生》有感:从历史到未来的技术变迁

观《中国数据库前世今生》有感&#xff1a;从历史到未来的技术变迁 在数字化浪潮中&#xff0c;数据库技术作为信息化建设的核心&#xff0c;承载了时代发展的脉搏。观看了纪录片《中国数据库前世今生》后&#xff0c;我深深感受到了中国数据库技术从无到有、从追赶到引领的艰…

深度残差网络ResNet简介

【图书推荐】《PyTorch深度学习与企业级项目实战》-CSDN博客 《PyTorch深度学习与企业级项目实战&#xff08;人工智能技术丛书&#xff09;》(宋立桓&#xff0c;宋立林)【摘要 书评 试读】- 京东图书 (jd.com) 卷积神经网络经典模型架构简介-CSDN博客 深度残差网络&#xf…

10分钟搞清楚为什么Transformer中使用LayerNorm而不是BatchNorm

1. Norm(Normalization) 首先&#xff0c;LayerNorm和BatchNorm的Norm是Normalization的缩写,不是Norm-范数。 Normalization在统计学中一般翻译为归一化&#xff0c;还有类似的是Standardization&#xff0c;一般翻译成标准化。这两个概念有什么区别呢&#xff1f; 归一化是…

vue2 + moment 实现日历,并带有上个月和下个月日期的日历

在 Vue 2 中使用 moment 库绘制一个带有上个月和下个月日期的日历&#xff0c;可以通过以下步骤实现。这个日历将显示当前月份的天数&#xff0c;以及前一个月和下一个月的部分日期&#xff08;通常为了让日历对齐为6行&#xff0c;每行7天&#xff09;。 主要步骤&#xff1a…

海睿思ABI——不只是BI,更多的是数据和智能

在当今这个数据洪流席卷各行各业的数字化时代&#xff0c;企业BI的建设已不再是可选项&#xff0c;而是驱动企业转型升级、实现精细化运营的必由之路。传统BI通过临时数据集直连业务系统&#xff0c;仅能展示预设报表和仪表盘&#xff0c;难以集成异构数据源&#xff0c;适应业…

【数学二】函数概念、常用函数、函数四大性质

考试要求 1、理解函数的概念&#xff0c;掌握函数的表示法&#xff0c;并会建立应用问题的函数关系. 2、了解函数的有界性、单调性、周期性和奇偶性. 3、理解复合函数及分段函数的概念、了解反函数及隐函数的概念。 4、掌握基本初等函数的性质及其图形、了解初等函数的概念。…

SpringCloud从零开始简单搭建 - JDK17

文章目录 SpringCloud Nacos从零开始简单搭建 - JDK17一、创建父项目二、创建子项目三、集成Nacos四、集成nacos配置中心 SpringCloud Nacos从零开始简单搭建 - JDK17 环境要求&#xff1a;JDK17、Spring Boot3、maven。 那么&#xff0c;如何从零开始搭建一个 SpringCloud …

PyQGIS开发 3 基础功能开发

PyQGIS开发 3 基础功能开发 1 添加图层树与地图视图 1.1 添加控件 1.2 Python代码 from PyQt5.QtCore import QMimeData from qgis.PyQt.QtWidgets import QMainWindow from qgis._core import QgsMapLayer, QgsRasterLayer, QgsVectorLayer from qgis.core import QgsProje…

美联储降息引爆股市,标普500指数逼近历史新高

在美联储宣布大幅降息后&#xff0c;股市迎来了强劲反弹。投资者信心大增&#xff0c;此前他们就预期美联储会降息0.5个百分点。周四的股市涨幅让标普500指数接近历史收盘最高点。 周四&#xff0c;标普500指数有望刷新历史纪录&#xff0c;此前美联储的大幅降息为市场注入了活…

基于STM32的智能门禁系统(指纹、蓝牙、刷卡、OLED、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STM32单片机&#xff0c;六个按键&#xff0c;分别代表指纹、蓝牙、刷卡的正确进门与错误进门&#xff1b; 比如第一个按键按下&#xff0c;表示指纹正确&#xff0c;OLED显示指纹正确&#x…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【内核启动】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 子系统开发内核 轻量系统内核&#xff08;LiteOS-M&#xff09; 轻量系统内核&#…

faiss安装 (CPU版本)

faiss版本 faiss-v1.7.4 cd faiss-v1.7.4cmake -B build . -DBUILD_TESTINGOFF -DFAISS_ENABLE_GPUOFF -DFAISS_ENABLE_PYTHONOFFmake -C build -j faiss&#xff1b; 默认安装路径如下 -- Installing: /usr/local/lib64/libfaiss.a -- Installing: /usr/local/include/faiss…

跨境平台通用测评技巧:解锁Temu、亚马逊等平台的销量密码

在当今竞争激烈的跨境电商行业&#xff0c;测评补单虽被视为“公开的秘密”&#xff0c;但无论是消费者还是平台方对此普遍持有反感态度。对于新手店铺而言&#xff0c;若缺乏价格和运营等方面的绝对优势&#xff0c;要在市场中生存下去尤为困难。因此&#xff0c;合理使用测评…

深入探讨IDSIPS:信息安全的未来趋势与应用

引言 在信息技术飞速发展的今天&#xff0c;网络安全问题愈发突出。随着数据泄露、网络攻击等事件频发&#xff0c;企业和个人对信息安全的重视程度不断提高。IDSIPS&#xff08;Intrusion Detection System and Intrusion Prevention System&#xff09;作为信息安全领域的重…

PowerShell install 一键部署Oracle12c

Oracle12c前言 Oracle 12c是甲骨文公司推出的一款关系数据库管理系统,它引入了多项创新特性,如多租户架构、大数据处理和云部署,适用于企业级应用。以下是Oracle 12c的详细介绍: Oracle 12c的主要特点 高性能:通过多线程处理、自动优化等技术,提高了数据库的查询和处理…

非标工业模型评审不再难,3D一览通助力高效协同

在当今工业领域&#xff0c;非标设备设计正成为满足特定客户需求的关键。这类设计服务涉及为特定应用场景量身定制的设备或机器&#xff0c;它们通常不是市场上现成的标准化产品&#xff0c;而是根据客户的独特需求进行个性化设计和制造。 这种定制化过程要求设计团队与客户进…

Abp vNext(五)集成MQTTnet,可收发消息

一 前言 MQTT的相关理论内容这里不做过多介绍&#xff0c;请看下面两篇文章&#xff1a; Introduction MQTT协议中文版 MQTT协议-CSDN博客 这篇文章只做代码实现&#xff0c;文章中使用MQTTnet作为MQTT开发的组件。 MQTT分为服务端和客户端&#xff0c;一个服务端对应多个…