🧱轉載自 Fundebug:https://blog.fundebug.com/2019/06/17/handling-errors-in-vuejs/
總的來說,Vue 中異常處理包含以下幾個方面:
- errorHandler
- warnHandler
- renderError
- errorCaptured
- window.onerror (不僅僅針對 Vue)
errorHandler
Vue.config.errorHandler = function(err, vm, info) {};
err
指代 error 對象,info
是一個 Vue 特有的字符串,vm
指代 Vue 應用本身。在一個頁面你可以有多個 Vue 應用,這個 errorHandler 作用到所有的應用。
Vue.config.errorHandler = function(err, vm, info) {
console.log(`Error: ${err.toString()}\nInfo: ${info}`);
};
第一種錯誤不會觸發 errorHandler,它只是一個 warning。
第二種錯誤會拋出錯誤被 errorHandler 捕獲:
Error: ReferenceError: x is not defined
Info: render
第三種錯誤也會被捕獲:
Error: ReferenceError: x is not defined
Info: v-on handler
warnHandler
warnHandler用來捕獲 Vue warning。在生產環境是不起作用的。
Vue.config.warnHandler = function(msg, vm, trace) {};
msg
和 vm
都容易理解,trace
代表了組件樹。請看下面的例子:
Vue.config.warnHandler = function(msg, vm, trace) {
console.log(`Warn: ${msg}\nTrace: ${trace}`);
};
第一個錯誤被 warnHandler
捕獲:
Warn: Property or method 'name' is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Trace:
(found in <Root>)
renderError
和前面兩個不同,renderError 不適用於全局,和組件相關,並且只適用於非生產環境。
下面是一個簡單的例子:
const app = new Vue({
el: "#app",
renderError(h, err) {
return h("pre", { style: { color: "red" } }, err.stack);
}
});
只是一個 warning。
errorCaptured
對於 errorCaptured ,文檔是這麼介紹的:
當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。
window.onerror
最後也是最重要的一個候選項 window.onerror。它是一個全局的異常處理函數,可以抓取所有的 JavaScript 異常。
window.onerror = function(message, source, line, column, error) {};
函數參數中的
source
代表當前的 URL。
如果你定義了onerror
,但是沒有啓用 Vue.config.errorHandler
,那麼有很多異常都抓不到。Vue 希望你定義它,否則異常不會拋出去的。如果定義 errorHandler
的代碼有 BUG,那麼運行起來也不會被 onerror
抓到。