Vue 错误处理 — onErrorCaptured 钩子

本文详细介绍了Vue框架中onErrorCaptured钩子的使用,包括如何捕获子组件错误、处理异步错误以及错误传播机制。通过示例代码展示了错误处理的最佳实践,帮助开发者更好地理解和应用Vue的错误管理。
摘要由CSDN通过智能技术生成

本文已整理到 👉 blog

如果我的内容帮助到了您,欢迎点个 Star 🎉🎉🎉 鼓励鼓励 :) ~~


Vue 实例有一个 onErrorCaptured 钩子,每当事件处理程序或生命周期钩子抛出错误时,Vue 会调用该钩子。

例如,下面的代码将增加一个计数器,每次单击按钮时,组件 test 都会抛出一个错误。

<template>
  <span id="count">{{ count }}</span>
  <test></test>
</template>

<script setup>
import { defineComponent, onErrorCaptured, ref } from 'vue'
import test from './test.vue'

const count = ref(0)
defineComponent({
  test
})

onErrorCaptured(err => {
  console.log('Caught error', err.message)
  ++count.value
  return false
})
</script>

test.vue

<template>
  <button @click="notAMethod()">Throw</button>
</template>

onErrorCaptured 只捕获嵌套组件中的错误

一个常见的问题是,当错误发生在注册 onErrorCaptured 钩子的同一组件中时,Vue 不会调用 onErrorCaptured

例如,如果从上述示例中删除 test 组件,并将按钮内联到顶级 Vue 实例中,Vue 将不会调用 onErrorCaptured

<template>
  <span id="count">{{ count }}</span>
  <button @click="notAMethod">Throw</button>
</template>

<script setup>
import { defineComponent, onErrorCaptured, ref } from 'vue'
import test from './test.vue'

const count = ref(0)
defineComponent({
  test
})

// Vue 不会调这个钩子,因为错误发生在这个 Vue 实例中,而不是子组件。
onErrorCaptured(err => {
  console.log('Caught error', err.message)
  ++count.value
  return false
})
</script>

异步错误

好的一面是,当异步函数抛出错误时,Vue 会调用 errorCapture()

例如,如果子组件异步抛出错误,Vue 仍然会将错误冒泡给父组件。

<template>
  <span id="count">{{ count }}</span>
  <test />
</template>

<script setup>
import { defineComponent, onErrorCaptured, ref } from 'vue'
import test from './test.vue'

const count = ref(0)
defineComponent({
  test
})

onErrorCaptured(err => {
  console.log('Caught error', err.message)
  ++count.value
  return false
})
</script>

test.vue

<template>
  <button @click="test">Throw</button>
</template>

<script setup>
// Vue 会将异步错误冒泡到父级的 onErrorCaptured(),因此每次单击该按钮时,
// Vue 都会调用带有 err的 errorCaptured() 钩子。err.message = 'Oops'
const test = async () => {
  await new Promise(resolve => setTimeout(resolve, 50))
  throw new Error('Oops!')
}
</script>

错误传播

在前面的示例中,您可能已经注意到 return false。如果 onErrorCaptured() 函数没有 return false,则 Vue 会将错误冒泡到父组件的 onErrorCaptured()

<template>
  <span id="count">{{ count }}</span>
  <test1 />
</template>

<script setup>
import { defineComponent, onErrorCaptured, ref } from 'vue'
import test1 from './test1.vue'

// 由于 test1 组件的 onErrorCaptured() 没有 return false,Vue 将冒泡显示错误。
const count = ref(0)
defineComponent({
  test1
})

onErrorCaptured(err => {
  console.log('Caught top-test error', err.message)
  ++count.value
  return false
})
</script>

test1.vue

<template>
  <test2 />
</template>

<script setup>
import { defineComponent, onErrorCaptured, ref } from 'vue'
import test2 from './test2.vue'

defineComponent({
  test2
})

onErrorCaptured(err => {
  console.log('test 1 error', err.message)
})
</script>

test2.vue

<template>
  <button @click="notAMethod()">Throw</button>
</template>
错误传播

另一方面,如果 onErrorCaptured() 方法使用 return false,Vue 将停止该错误的传播:

// test2.vue
onErrorCaptured(err => {
  console.log('test 1 error', err.message)
  return false
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值