優(yōu)雅的處理vue項(xiàng)目異常實(shí)戰(zhàn)記錄
背景
- 你還在為處理Uncaught (in promise) ReferenceError煩惱嗎?
- 你還在為捕獲異常反復(fù)的寫try catch嗎?
- 你還在為每一個promise寫catch嗎?
是時候一站式統(tǒng)一處理異常?。。。ㄡ槍ue項(xiàng)目)
全局異常捕獲
Vue.config.errorHandler = function (err, vm, info) { // 指定組件的渲染和觀察期間未捕獲錯誤的處理函數(shù)。這個處理函數(shù)被調(diào)用時,可獲取錯誤信息和 Vue 實(shí)例。 // 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+node 實(shí)現(xiàn)視頻在線播放的實(shí)例代碼
這篇文章主要介紹了vue+node 實(shí)現(xiàn)視頻在線播放的實(shí)例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Vue 中如何利用 new Date() 獲取當(dāng)前時間
在 Vue 開發(fā)中,利用 new Date() 方法可以方便地獲取當(dāng)前時間,并通過 Date 對象的方法進(jìn)行時間格式化和操作。通過本文的介紹,您應(yīng)該對在 Vue 中獲取當(dāng)前時間有了更深入的了解,并了解了一些常見的時間操作方法,需要的朋友可以參考下2023-07-07Vue 引入AMap高德地圖的實(shí)現(xiàn)代碼
這篇文章主要介紹了Vue 引入AMap高德地圖的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04解決vue中axios設(shè)置超時(超過5分鐘)沒反應(yīng)的問題
這篇文章主要介紹了解決vue中axios設(shè)置超時(超過5分鐘)沒反應(yīng)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Vue2與Vue3如何利用install自定義全局確認(rèn)框組件編寫
這篇文章主要介紹了Vue2與Vue3如何利用install自定義全局確認(rèn)框組件編寫方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03Vue.js 2.0學(xué)習(xí)教程之從基礎(chǔ)到組件詳解
這篇文章主要介紹了Vue.js 2.0從基礎(chǔ)到組件的相關(guān)資料,文中介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用vue.js具有一定的參考價值,需要的朋友可以參考學(xué)習(xí),下面來一起看看吧。2017-04-04