vue 异常统一处理,vue全局错误处理
本文主要介绍使用pyscript在网页中编写Python程序的方法。通过示例代码详细介绍,对大家的学习或工作有一定的参考价值。有需要的朋友下面跟边肖学习。
:
目录
1.常见前端异常2。简单的全局异常处理3。如何在Vue3 4中实现异常处理?在开发组件库或插件时,经常需要全局异常处理来实现:\
全局处理异常;为开发人员提示错误信息;方案退化等等。那么如何实现以上功能呢?本文简单实现了一种异常处理方法,然后详细介绍了在Vue3源代码中的实现。最后总结了异常处理的几个核心。
本文的Vue3版本是3.0.11。
一、前端常见异常
对于前端,有许多常见的例外,例如:
JS语法异常;Ajax请求异常;静态资源加载异常;承诺例外;Iframe异常;等等
最常用的例子有:\
window.onerror根据window.onerror文档[2],JS运行时出现错误(包括语法错误)时,触发window.onerror():
window.onerror=function(消息,源,行号,列号,错误){
Console.log(捕获到异常:,{消息,源,行号,列号,错误});
}
功能参数:
消息:错误消息(字符串)。可用于HTMLonerror= 处理程序中的事件。Source:带错误的脚本URL(string)line no:带错误的行号(number) colno:带错误的列号(number)Error:Error object(object)如果此函数返回true,将阻止默认事件处理函数的执行。
try...catch异常处理另外,我们经常使用try.处理异常的catch语句:
尝试{
//做点什么
} catch(错误){
console.error(错误);
}
更多应对方法,可以看之前推荐的文章。
思考可以考虑一下。你在业务发展的过程中经常要处理这些错误吗?那么,像Vue3这样的复杂库也通过try处理异常吗.到处抓?接下来我们来看看。
二、实现简单的全局异常处理
在开发插件或库时,我们可以通过try封装一个全局异常处理方法.捕捉并传入要作为参数执行的方法。调用者只需要关心调用结果,不需要知道全局异常处理方法的内部逻辑。一般使用方法如下:
const errorHandling=(fn,args)={
让结果;
尝试{
result=args?fn(.args):fn();
} catch(错误){
console.error(错误)
}
返回结果;
}
测试它:
常量f1=()={
console.log([f1运行])
抛出新错误([f1错误!])
}
错误处理(f1);
/*
输出:
[f1跑步]
错误:[f1错误!]
在f1(/用户/王平安/利奥/www/node/www/a.js:14:11)
在错误处理(/用户/王平安/利奥/www/node/www/a.js:4:39)
at object . anonymous(/Users/王平安/利奥/www/node/www/a.js:17:1)
在模块处。_compile(节点:internal/modules/cjs/loader:1095:14)
at Object.Module._extensions.js(节点:internal/modules/cjs/loader:1147:10)
at Module.load(节点:internal/modules/cjs/loader:975:32)
at Function.Module._load(节点:internal/modules/cjs/loader:822:12)
at function . executeuserentrypoint[as run main](节点:internal/modules/run _ main:81:12)
在节点:内部/主/运行主模块:17:47
*/
如您所见,当您需要对一个方法进行异常处理时,只需将该方法作为参数传入即可。但是,上面的例子和实际业务发展的逻辑有点不同。在实际业务中,我们经常会遇到方法的嵌套调用,我们来试试:
常量f1=()={
console.log([f1])
F2();
}
常数f2=()={
console.log([f2])
F3();
}
常量f3=()={
console.log([f3])
抛出新错误([f3错误!])
}
错误处理(f1)
/*
输出:
[f1跑步]
[f2运行]
[f3运行]
错误:[f3错误!]
在F3(/用户/王平安/利奥/www/node/www/a.js:24:11)
在二楼(/用户/王平安/利奥/www/node/www/a.js:19:5)
在f1(/用户/王平安/利奥www/node/www/a.js:14:5)
在错误处理(/用户/王平安/利奥www/node/www/a.js:4:39)
at对象。匿名(/用户/王平安/利奥/www/node/www/a.js:27:1)
在模块处.编译(节点:内部/模块/cjs/加载程序:1095:14)
at Object.Module._extensions.js(节点:内部/模块/cjs/加载程序:1147:10)
在模块加载时(节点:内部/模块/cjs/加载程序:975:32)
在Function.Module._load(节点:内部/模块/cjs/加载程序:822:12)
在功能上。executeuserentrypoint[as run main](节点:内部/模块/run _ main:81:12)
*/
这样也是没问题的。那么接下来就是在错误处理方法的捕捉分支实现对应异常处理即可。接下来看看Vue3源码中是如何处理的?
三、Vue3如何实现异常处理
理解完上面示例,接下来看看在Vue3源码中是如何实现异常处理的,其实现起来也是很简单。
实现异常处理方法在errorHandling.ts文件中定义了callWithErrorHandling和callWithAsyncErrorHandling两个处理全局异常的方法。顾名思义,这两个方法分别处理:
callWithErrorHandling:处理同步方法的异常;callWithAsyncErrorHandling:处理异步方法的异常。使用方式如下:
callWithAsyncErrorHandling(
处理者,
实例,
错误代码。组件事件处理程序,
一个参数名
)
代码实现大致如下:
//packages/runtime-core/src/错误处理。分时(同timesharing)
//处理同步方法的异常
导出函数callWithErrorHandling(
fn:功能,
实例:ComponentInternalInstance null,
类型:错误类型,
args?未知[]
) {
let res
尝试{
res=args?fn(.args):fn();//调用原方法
} catch (err) {
handleError(错误,实例,类型)
}
返回资源
}
//处理异步方法的异常
导出函数callWithAsyncErrorHandling(
fn: Function Function[],
实例:ComponentInternalInstance null,
类型:错误类型,
args?未知[]
):any[] {
//省略其他代码
const RES=callWithErrorHandling(fn,instance,type,args)
if (res isPromise(res)) {
res.catch(err={
handleError(错误,实例,类型)
})
}
//省略其他代码
}
callWithErrorHandling方法处理的逻辑比较简单,通过简单的尝试.捕捉做一层封装。而callWithAsyncErrorHandling方法就比较巧妙,通过将需要执行的方法传入callWithErrorHandling方法处理,并将其结果通过。捕捉方法进行处理。
处理异常在上面代码中,遇到报错的情况,都会通过handleError()处理异常。其实现大致如下:
//packages/runtime-core/src/错误处理。分时(同timesharing)
//异常处理方法
导出函数句柄错误(
错误:未知,
实例:ComponentInternalInstance null,
类型:错误类型,
throwInDev=true
) {
//省略其他代码
logError(err,type,contextVNode,throwInDev)
}
函数日志错误(
错误:未知,
类型:错误类型,
contextVNode: VNode null,
throwInDev=true
) {
//省略其他代码
控制台.错误(错误)
}
保留核心处理逻辑之后,可以看到这边处理也是相当简单,直接通过控制台.错误(错误)输出错误内容。
配置errorHandler自定义异常处理函数在使用Vue3时,也支持「指定自定义异常处理函数」,来处理「组件渲染函数」和「侦听器执行期间」抛出的未捕获错误。这个处理函数被调用时,可获取错误信息和相应的应用实例。文档参考: 《errorHandler》 使用方法如下,在项目主页。射流研究…文件中配置:
//src/main.js
app.config.errorHandler=(err,vm,info)={
//处理错误
//`信息是某视频剪辑软件特定的错误信息,比如错误所在的生命周期钩子
}
那么错误处理程序()是何时执行的呢?我们继续看看源码中handleError()的内容,可以发现:
//packages/runtime-core/src/错误处理。分时(同timesharing)
导出函数句柄错误(
错误:未知,
实例:ComponentInternalInstance null,
类型:错误类型,
throwInDev=true
) {
const contextVNode=instance?instance.vnode : null
如果(实例){
//省略其他代码
//读取错误处理程序配置项
const appErrorHandler=实例。应用程序上下文。配置。错误处理程序
if (appErrorHandler) {
callWithErrorHandling(
appErrorHandler,
空,
错误代码。应用程序错误处理程序,
[错误,暴露实例,错误信息]
)
返回
}
}
logError(err,type,contextVNode,throwInDev)
}
通过实例。应用程序上下文。配置。错误处理程序取到全局配置的自定义错误处理函数,存在时则执行,当然,这边也是通过前面定义的callWithErrorHandling来调用。
调用errorCaptured生命周期钩子在使用Vue3的时候,也可以通过错误被捕获生命周期钩子来「捕获来自后代组件的错误」。文档参考: 《errorCaptured》 入参如下:
(err: Error,instance: Component,info: string)=?布尔型
此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回错误的以「阻止该错误继续向上传播。」有兴趣的同学可以通过文档,「查看具体的错误传播规则」。使用方法如下,父组件监听onErrorCaptured生命周期(示例代码使用vue 3设置语法):
模板
消息/消息
/模板
脚本设置
//App.vue
从“vue”导入{ onErrorCaptured };
从导入邮件 components/Message.vue
onErrorCaptured(函数(错误,实例,信息){
console.log([errorCaptured]),错误,实例,信息)
})
/脚本
子组件如下:
模板
button @click=sendMessage 发送消息/按钮
/模板
脚本设置
//Message.vue
const sendMessage=()={
抛出新错误([test onErrorCaptured])
}
/脚本
当点击「发送消息」按钮,控制台便输出错误:
[捕获的错误]错误:[testonErrorCaptured]
在代理处。sendmessage(消息。vue:36:15)
at _ createelementvnode。onclick。_ cache。计算出来的。_ cache。计算的(消息。vue:3:39)
atcallWithErrorHandling(运行时-核心。埃斯姆邦德勒。联署材料:6706:22)
atcallwithsyncerrorhandling(运行时-核心。埃斯姆邦德勒。联署材料:6715:21)
athtmlbuttonelement。invoker(运行时-DOM。埃斯姆邦德勒。js:350:13)代理{ sendMessage:\u,…}本地事件处理程序
可以看到onErrorCaptured生命周期钩子正常执行,并输出子组件Message.vue内的异常。
那么这个又是如何实现呢?还是看errorHandling.ts中的handleError()方法:
//packages/runtime-core/src/错误处理。分时(同timesharing)
导出函数句柄错误(
错误:未知,
实例:ComponentInternalInstance null,
类型:错误类型,
throwInDev=true
) {
const contextVNode=instance?instance.vnode : null
如果(实例){
let cur=instance.parent
//公开的实例是呈现代理,使其与2.x保持一致
const公开实例=实例。代理人
//在生产中,挂钩只接收错误代码
const errorInfo=__DEV__?错误类型字符串[类型]:类型
while (cur) {
const error capturedhooks=cur。EC//取出组件配置的错误被捕获生命周期方法
if (errorCapturedHooks) {
//循环执行错误被捕获中的每个钩
对于(设I=0;I error captured books . length I){
如果(
errorCapturedHooks[i](err,exposedInstance,errorInfo i)===false
) {
返回
}
}
}
cur=cur.parent
}
//省略其他代码
}
logError(err,type,contextVNode,throwInDev)
}
这边会先获取实例。父级作为当前处理的组件实例进行递归,每次将取出组件配置的错误被捕获生命周期方法的数组并循环调用其每一个钩子,然后再取出当前组件的父组件作为参数,最后继续递归调用下去。
实现错误码和错误消息Vue3还为异常定义了错误码和错误信息,在不同的错误情况有不同的错误码和错误信息,让我们能很方便定位到发生异常的地方。错误码和错误信息如下:
//packages/runtime-core/src/错误处理。分时(同timesharing)
导出常量枚举错误代码{
设置_功能,
渲染函数,
WATCH_GETTER,
手表_回调,
//.省略其他。
}
导出常量错误类型字符串:Recordnumber string,string={
//省略其他
【生命周期看。RENDER_TRACKED]: renderTracked挂钩,
【生命周期看。RENDER _ TRIGGERED]: RENDER TRIGGERED hook ,
[错误代码。SETUP_FUNCTION]:设置函数,
[错误代码。RENDER_FUNCTION]:渲染函数,
//省略其他
[错误代码。调度程序]:
调度程序刷新。这可能是Vue内部的一个错误。
请在https://new-issue.vuejs.org/? repo=vue js/vue-next 打开一个问题
}
针对不同的错误情况,根据错误代码获取错误类型字符串的错误信息进行提示:
//packages/runtime-core/src/error handling . ts
函数日志错误(
错误:未知,
类型:错误类型,
contextVNode: VNode null,
throwInDev=true
) {
if (__DEV__) {
const info=ErrorTypeStrings[type]
warn(`未处理的错误${info?`在${info}`执行期间:` `} `)
//省略其他
}否则{
console.error(错误)
}
}
实现TreeShaking对于Vue3实现TreeShaking的介绍,可以看我之前的高效实现框架和JS库瘦身[7]。其中,logError方法用于:
//packages/runtime-core/src/error handling . ts
函数日志错误(
错误:未知,
类型:错误类型,
contextVNode: VNode null,
throwInDev=true
) {
if (__DEV__) {
//省略其他
}否则{
console.error(错误)
}
}
当编译到生产环境中时,__DEV__分支的代码将不会被打包,从而优化了包的大小。
四、总结
通过以上部分,我们已经基本搞清楚了Vue3中全局异常处理的核心逻辑。在开发我们自己的错误处理方法时,我们也可以考虑这些核心要点:
支持同步和异步异常处理;设置业务错误代码和业务错误信息;支持自定义错误处理方法;支持开发环境的错误提示;支持摇树。这几点可以在你设计插件的时候考虑到~
关于Vue中全局异常处理的几种方案的文章到此结束。有关Vue中全局异常的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。