優(yōu)雅的處理vue項目異常實戰(zhàn)記錄
背景
- 你還在為處理Uncaught (in promise) ReferenceError煩惱嗎?
- 你還在為捕獲異常反復(fù)的寫try catch嗎?
- 你還在為每一個promise寫catch嗎?
是時候一站式統(tǒng)一處理異常?。。。ㄡ槍ue項目)
全局異常捕獲
Vue.config.errorHandler = function (err, vm, info) {
// 指定組件的渲染和觀察期間未捕獲錯誤的處理函數(shù)。這個處理函數(shù)被調(diào)用時,可獲取錯誤信息和 Vue 實例。
// handle error
// `info` 是 Vue 特定的錯誤信息,比如錯誤所在的生命周期鉤子
// 只在 2.2.0+ 可用
}
注意:面對異常處理,同步異常和異步異常應(yīng)該區(qū)別對待分別處理。
vue核心源碼剖析
通過閱讀源碼看一下vue是如何將Vue.config.errorHandler接口暴露給使用者。
同步異常處理方案
// 定義異常處理函數(shù),判斷用戶是否自定義Vue.config.errorHandler,定義則直接調(diào)用,未定義執(zhí)行vue本身異常處理。
function globalHandleError(err, vm, info) {
if (Vue.config.errorHandler) {
try {
return config.errorHandler.call(null, err, vm, info)
} catch (e) {
logError(e, null, 'config.errorHandler');
}
}
logError(err, vm, info);
}
try {
// vue正常執(zhí)行代碼被包裹在try內(nèi),有異常會調(diào)用globalHandleError
} catch (e) {
globalHandleError(e, vm, '對應(yīng)信息');
}
異步異常處理方案
// 定義異步異常處理函數(shù),對于自身沒有捕獲異常的promise統(tǒng)一執(zhí)行catch
function invokeWithErrorHandling(
handler,
context,
args,
vm,
info
) {
var res;
try {
res = args ? handler.apply(context, args) : handler.call(context);
if (res && !res._isVue && isPromise(res) && !res._handled) {
res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
// 異步代碼例如promise可以統(tǒng)一為其定義Promise.prototype.catch()方法。
res._handled = true;
}
} catch (e) {
handleError(e, vm, info);
}
return res
}
// 所有的鉤子函數(shù)調(diào)用異常處理函數(shù)
function callHook(vm, hook) {
var handlers = vm.$options[hook];
// 為所有鉤子增加異常處理
var info = hook + " hook";
if (handlers) {
for (var i = 0, j = handlers.length; i < j; i++) {
invokeWithErrorHandling(handlers[i], vm, null, vm, info);
}
}
}
知識延伸
// vue接口是能處理同步異常以及部分鉤子中的異步異常,對于方法中的異常無法有效處理,我們可以仿照源碼增加方式中的異步異常處理,避免為每一個promise寫catch
Vue.mixin({
beforeCreate() {
const methods = this.$options.methods || {}
Object.keys(methods).forEach(key => {
let fn = methods[key]
this.$options.methods[key] = function (...args) {
let ret = fn.apply(this, args)
if (ret && typeof ret.then === 'function' && typeof ret.catch === "function") {
return ret.catch(Vue.config.errorHandler)
} else { // 默認(rèn)錯誤處理
return ret
}
}
})
}
})
完整代碼
下面是全局處理異常的完整代碼,已經(jīng)封裝成一個插件
errorPlugin.js
/**
* 全局異常處理
* @param {
* } error
* @param {*} vm
*/
const errorHandler = (error, vm, info) => {
console.error('拋出全局異常')
console.error(vm)
console.error(error)
console.error(info)
}
let GlobalError = {
install: (Vue, options) => {
/**
* 全局異常處理
* @param {
* } error
* @param {*} vm
*/
Vue.config.errorHandler = errorHandler
Vue.mixin({
beforeCreate() {
const methods = this.$options.methods || {}
Object.keys(methods).forEach(key => {
let fn = methods[key]
this.$options.methods[key] = function (...args) {
let ret = fn.apply(this, args)
if (ret && typeof ret.then === 'function' && typeof ret.catch === "function") {
return ret.catch(errorHandler)
} else { // 默認(rèn)錯誤處理
return ret
}
}
})
}
})
Vue.prototype.$throw = errorHandler
}
}
export default GlobalError
使用
// 在入口文件中引入 import ErrorPlugin from './errorPlugin' import Vue from 'vue' Vue.use(ErrorPlugin)
寫在最后
增加全局異常處理有助于
- 提高代碼健壯性
- 減少崩潰
- 快速定位bug
資料參考
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動效果
使用postgres(postgis)數(shù)據(jù)庫以及nodejs作為后臺,vue和openlayers做前端,openlayers使用http請求通過nodejs從postgres數(shù)據(jù)庫獲取數(shù)據(jù),這篇文章主要介紹了vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動,需要的朋友可以參考下2024-05-05
vue 單頁應(yīng)用和多頁應(yīng)用的優(yōu)劣
這篇文章主要介紹了vue 單頁應(yīng)用和多頁應(yīng)用的優(yōu)劣,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下2020-10-10
element el-input directive數(shù)字進(jìn)行控制
本文介紹了vue使用directive 進(jìn)行控制的方法,使用element開發(fā)的過程中遇到循環(huán)的數(shù)據(jù)只能輸入數(shù)字,并且有不要小數(shù)點,有需要小數(shù)點的,就有一定的參考價值,有興趣的可以了解一下2018-10-10
vite+vue3不清除瀏覽器緩存直接下載最新代碼的解決方案
vite+vue3項目發(fā)布后,瀏覽器上還是舊代碼,沒有及時更新到最新代碼,下面通過本文給大家分享vite+vue3不清除瀏覽器緩存直接下載最新代碼的解決方案,感興趣的朋友一起看看吧2024-06-06

