本文已整理到 ?? blog依许。
如果我的內(nèi)容幫助到了您鳖粟,歡迎點個 Star
?????? 鼓勵鼓勵 :) ~~
Vue 實例有一個 onErrorCaptured
鉤子盟榴,每當(dāng)事件處理程序或生命周期鉤子拋出錯誤時腕扶,Vue 會調(diào)用該鉤子栅贴。
例如著瓶,下面的代碼將增加一個計數(shù)器瞳秽,每次單擊按鈕時瓣履,組件 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
只捕獲嵌套組件中的錯誤
一個常見的問題是练俐,當(dāng)錯誤發(fā)生在注冊 onErrorCaptured
鉤子的同一組件中時袖迎,Vue 不會調(diào)用 onErrorCaptured
。
例如腺晾,如果從上述示例中刪除 test
組件燕锥,并將按鈕內(nèi)聯(lián)到頂級 Vue 實例中,Vue 將不會調(diào)用 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 不會調(diào)這個鉤子归形,因為錯誤發(fā)生在這個 Vue 實例中,而不是子組件鼻由。
onErrorCaptured(err => {
console.log('Caught error', err.message)
++count.value
return false
})
</script>
異步錯誤
好的一面是暇榴,當(dāng)異步函數(shù)拋出錯誤時,Vue 會調(diào)用 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 都會調(diào)用帶有 err的 errorCaptured() 鉤子哈误。err.message = 'Oops'
const test = async () => {
await new Promise(resolve => setTimeout(resolve, 50))
throw new Error('Oops!')
}
</script>
錯誤傳播
在前面的示例中,您可能已經(jīng)注意到 return false
躏嚎。如果 onErrorCaptured()
函數(shù)沒有 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
})