欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式?

 更新時(shí)間:2022年04月21日 14:29:31   作者:諸葛小徹  
本文主要介紹了如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

背景

在開(kāi)發(fā)Vue項(xiàng)目時(shí),使用瀏覽器調(diào)試可以比較清晰的看到報(bào)的什么錯(cuò)、在哪報(bào)錯(cuò),或者使用console.log()打印出報(bào)錯(cuò)信息,以便快速定位到報(bào)錯(cuò)源頭并解決,但是如果項(xiàng)目上線(xiàn)了又怎么查看呢。對(duì)于上線(xiàn)項(xiàng)目來(lái)說(shuō),一般都是會(huì)有代碼混淆以及禁用console.log(),這個(gè)時(shí)候再使用瀏覽器調(diào)試就有點(diǎn)不太方便了。另一種場(chǎng)景,如果要做一個(gè)前端報(bào)錯(cuò)監(jiān)控平臺(tái),那這些報(bào)錯(cuò)信息又應(yīng)該如何收集呢。本文就重點(diǎn)介紹四種方式,即error、unhandledrejection、errorHandler、errorCaptured,用于監(jiān)聽(tīng)Vue項(xiàng)目可能遇到的報(bào)錯(cuò)。

onerror

當(dāng)JavaScript運(yùn)行時(shí)錯(cuò)誤,包括語(yǔ)法錯(cuò)誤,則window會(huì)觸發(fā)ErrorEvent接口的error事件,并執(zhí)行window.onerror()方法,用于處理監(jiān)聽(tīng)到的錯(cuò)誤。
如果是資源加載失敗,包括img的src加載失敗或者引入的script加載失敗,則加載資源的元素會(huì)觸發(fā)Event接口的error事件,并指定該元素上的onerror()方法處理錯(cuò)誤。這些error不會(huì)冒泡到window,也就是說(shuō)window.onerror將無(wú)法監(jiān)聽(tīng)到報(bào)錯(cuò)。

特點(diǎn):

  • 可以監(jiān)聽(tīng)所有的JavaScript錯(cuò)誤,也能監(jiān)聽(tīng)Vue組件的報(bào)錯(cuò),包括一些異步錯(cuò)誤
  • 無(wú)法根據(jù)報(bào)錯(cuò)識(shí)別Vue組件的詳細(xì)信息,也無(wú)法監(jiān)聽(tīng)已經(jīng)被try/catch捕獲的錯(cuò)誤
  • 無(wú)法監(jiān)聽(tīng)資源加載失敗的報(bào)錯(cuò)

window.onerror

window.onerror接收4個(gè)參數(shù),分別是:

  • message: 錯(cuò)誤信息
  • source:發(fā)生錯(cuò)誤的資源
  • line:發(fā)生錯(cuò)誤的行號(hào)
  • column:發(fā)生錯(cuò)誤的列數(shù)
  • error:Error錯(cuò)誤對(duì)象

完整用法:

window.onerror = function(message,source,line,column,error) {
    // do something
};

如果函數(shù)返回true,則會(huì)阻止執(zhí)行默認(rèn)事件處理函數(shù)。

window.addEventListener('error')

使用事件監(jiān)聽(tīng),并在全局監(jiān)聽(tīng)error事件。使用效果同window.onerror類(lèi)似,語(yǔ)法有所差異:

window.addEventListener('error', event => {});

注意:此event指的是ErrorEvent類(lèi)型,包含了有關(guān)事件以及具體的錯(cuò)誤信息
舉個(gè)栗子:(本文涉及的示例代碼都是基于Vue項(xiàng)目,下同)

// App.vue
// window.onerror是全局監(jiān)聽(tīng),因此放在入口是比較合理的,盡管也可以放在其他位置
...
<script>
export default {
    mounted() {
        window.onerror = function(message,source,line,column,error) {
            console.log('window.onerror----', message,source,line,column,error);
        }
        // 效果與上一個(gè)類(lèi)似,都是掛載到全局,兩者使用其一即可。如果兩者都使用,會(huì)重復(fù)處理error
        window.addEventListener('error', event => {
            console.log('window error on listener---', event);
        })
    }
}
</script>
...

element.onerror

針對(duì)一些資源加載失敗的情況,例如img、script,將會(huì)觸發(fā)該元素的onerror()處理函數(shù),并且error不會(huì)冒泡到window。遇到這種情況,可以手動(dòng)拋出異常,就可以被全局異常監(jiān)聽(tīng)到是資源加載失敗了。

舉個(gè)栗子

// child.vue
// 圖片資源加載失敗
<img src="123" alt="" @error="event => handleError(event)" />
...
handleError(event) {
    console.log('handleError-----', event);
    throw new Error('圖片加載失敗了'); // 手動(dòng)拋出異常,以便全局事件可以監(jiān)聽(tīng)到
}

errorHandler

Vue全局錯(cuò)誤監(jiān)聽(tīng)處理,所有組件的錯(cuò)誤信息默認(rèn)都會(huì)匯總到此。
由于errorHandler是全局配置的,因此window.onerror將會(huì)“失效”,即errorHandler能捕獲的錯(cuò)誤,onerror將不能捕獲;errorHandler不能捕獲的異常,onerror將捕獲錯(cuò)誤。如果errorCaptured函數(shù)返回為false,那么此error將不會(huì)傳到errorHandler

舉個(gè)栗子

// main.js
...
const app = createApp(App)
app.config.errorHandler = (err, vm info) => {
    console.log('errorHandle', err, vm, info);
    // err,錯(cuò)誤對(duì)象
    // vm,發(fā)生錯(cuò)誤的組件實(shí)例
    // info,Vue特定的錯(cuò)誤信息,例如錯(cuò)誤發(fā)生的生命周期、錯(cuò)誤發(fā)生的事件
}

errorCaptured

errorCaptured是Vue生命周期中的一個(gè),用于捕獲當(dāng)前組件的所有后代組件產(chǎn)生的錯(cuò)誤。函數(shù)如果返回為false,則會(huì)阻止error繼續(xù)上傳,全局的錯(cuò)誤監(jiān)聽(tīng)將不能捕獲該error;否則,全局的錯(cuò)誤監(jiān)聽(tīng)也會(huì)再處理error。

此鉤子接收三個(gè)參數(shù):

  • error:Error錯(cuò)誤對(duì)象
  • vm:發(fā)生錯(cuò)誤的組件實(shí)例,可訪(fǎng)問(wèn)組件屬性
  • info:包含錯(cuò)誤來(lái)源信息的字符串

在鉤子函數(shù)中,可以修改組件的狀態(tài)

error傳播規(guī)則(劃重點(diǎn))

  • 默認(rèn)情況下,如果定義了全局的errorHandler,所有的error都將最終匯總到errorHandler中做統(tǒng)一處理
  • 如果一個(gè)組件的繼承鏈或父鏈存在多個(gè)errorCaptured鉤子,則這些鉤子將會(huì)被相同的錯(cuò)誤逐級(jí)喚起。
  • 如果當(dāng)前組件的errorCaptured鉤子本身繼續(xù)拋出錯(cuò)誤,那么這些新的錯(cuò)誤和原本的錯(cuò)誤都將上傳到父級(jí)組件的errorCaptured鉤子,以及匯總到errorHandler
  • 如果一個(gè)errorCaptured鉤子返回了false,則會(huì)阻止此error的繼續(xù)向上傳播,也就是說(shuō)這個(gè)error到此就已經(jīng)處理完畢了。這個(gè)會(huì)阻止其他任何被這個(gè)錯(cuò)誤喚起的errorCaptured鉤子以及全局的errorHandler。

tips:如果errorCaptured本身拋出error,return false也就不會(huì)執(zhí)行了。

舉個(gè)栗子也許更能說(shuō)明白

代碼寫(xiě)的比較簡(jiǎn)潔,但是“言簡(jiǎn)意賅”

// main.js
const app = createApp(App)
app.config.errorHandler = (err, vm info) => {
    console.log('errorHandle', err, vm, info); // errorHandler也會(huì)執(zhí)行兩次
    // err,錯(cuò)誤對(duì)象
    // vm,發(fā)生錯(cuò)誤的組件實(shí)例
    // info,Vue特定的錯(cuò)誤信息,例如錯(cuò)誤發(fā)生的生命周期、錯(cuò)誤發(fā)生的事件
}
// App.vue
...
<!-- 引入父組件,并注冊(cè)組件 -->
<FatherErrorDemo />
...
errorCaptured: (err, vm, info) => {
    console.log('根組件 捕獲異常 errorCaptured', err,vm,info)
    // 根組件的errorCaptured會(huì)執(zhí)行兩次,先捕獲FatherErrorDemo鉤子自身的錯(cuò)誤,然后捕獲childErrorDemo的錯(cuò)誤
    // 因此vm也分別指向FatherErrorDemo和childErrorDemo
    console.log('根組件 vm', vm.$data);
    // return false;
}
// FatherErrorDemo.vue
...
<div>
this is FatherErrorDemo
<!-- 引入子組件,并注冊(cè)組件 -->
<childErrorDemo />
</div>
...
errorCaptured: (err, vm, info) => {
    console.log('父組件 錯(cuò)誤捕獲', err,vm,info);
    console.log('父組件 vm', vm.$data); // vm 指向childErrorDemo實(shí)例
    this.father(); // 未定義,此處會(huì)拋出錯(cuò)誤。errorCaptured鉤子函數(shù)自身產(chǎn)生錯(cuò)誤
    // return false;
}
// childErrorDemo.vue
...
<div>
this is childErrorDemo
</div>
...
mounted() {
    this.child(); // 未定義,會(huì)拋出錯(cuò)誤
}

執(zhí)行結(jié)果:

根據(jù)執(zhí)行過(guò)程可知:

  • 每一個(gè)error產(chǎn)生后,將從產(chǎn)生error的組件,逐級(jí)上傳到父級(jí)組件的errorCaptured,直到根節(jié)點(diǎn),最后匯總到errorHandler。表示error完整的生命周期
  • errorCaptured返回false,將會(huì)阻止當(dāng)前error向上傳遞,errorHandler也就收不到此error。(本處未執(zhí)行相關(guān)代碼)
  • errorCaptured自身的error,將會(huì)優(yōu)先向上傳遞,直到“被處理”或者到達(dá)errorHandler。然后才會(huì)傳遞捕獲到的子組件錯(cuò)誤。

如何監(jiān)聽(tīng)異步錯(cuò)誤

異步錯(cuò)誤無(wú)法直接使用Vue的errorCaptured和errorHandler來(lái)監(jiān)聽(tīng),根據(jù)異步類(lèi)型的不同,處理方式有所差異。一般來(lái)說(shuō),監(jiān)聽(tīng)異步錯(cuò)誤,多采用window.onerror,如果是監(jiān)聽(tīng)Promise的錯(cuò)誤,則使用unhandledrejection事件來(lái)監(jiān)聽(tīng)。

舉個(gè)栗子吧

// main.js
const app = createApp(App)
app.config.errorHandler = (err, vm info) => {
    console.log('errorHandle', err, vm, info); // errorHandler不會(huì)被調(diào)用
    // err,錯(cuò)誤對(duì)象
    // vm,發(fā)生錯(cuò)誤的組件實(shí)例
    // info,Vue特定的錯(cuò)誤信息,例如錯(cuò)誤發(fā)生的生命周期、錯(cuò)誤發(fā)生的事件
}
// App.vue
...
<!-- 引入父組件,并注冊(cè)組件 -->
<FatherErrorDemo />
...
mounted() {
    window.onerror = function(msg,source,line,column,err) {
      console.log('window.onerror----', msg,source,line,column,err);
      return true;
    }
    window.addEventListener('unhandledrejection', event => {
      console.log('監(jiān)聽(tīng)Promise unhandledrejection', event)
    })
},
errorCaptured: (err, vm, info) => {
    // errorCaptured不會(huì)被調(diào)用
    console.log('根組件 捕獲異常 errorCaptured', err,vm,info)
    console.log('根組件 vm', vm.$data);
    // return false;
}
// FatherErrorDemo.vue
...
<div>
this is FatherErrorDemo
</div>
...
mounted() {
    setTimeout(() => {
        this.father();
    }, 1000); // 異步執(zhí)行
    new Promise((resolve, reject) => {
      this.father();
      resolve();
    })
}

執(zhí)行結(jié)果

由此可見(jiàn),Vue的鉤子和配置函數(shù)并沒(méi)有執(zhí)行,但是window.onerror、unhandledrejection卻可以捕獲到錯(cuò)誤。

為了不寫(xiě)重復(fù)代碼,setTimeout和Promise我放在一起了。實(shí)際上,Promise的產(chǎn)生錯(cuò)誤且沒(méi)有被reject處理,那么可以通過(guò)監(jiān)聽(tīng)unhandledrejection事件來(lái)捕獲異常。setTimeout產(chǎn)生的錯(cuò)誤也只能用window.onerror來(lái)捕獲(使用window.addEventListener('error')也是一樣)。

總結(jié)

  • 本文共總結(jié)了4種常見(jiàn)的監(jiān)聽(tīng)錯(cuò)誤的方法,監(jiān)聽(tīng)方法沒(méi)有對(duì)錯(cuò),只有使用場(chǎng)景的不同
  • 在Vue環(huán)境中,大多數(shù)錯(cuò)誤可使用errorHandler配置和errorCaptured鉤子解決,但是不能處理異步錯(cuò)誤
  • 異步錯(cuò)誤根據(jù)類(lèi)型的不同,可全局監(jiān)聽(tīng)error和unhandledrejection事件
  • 全局捕獲錯(cuò)誤,可便于快速排查并定位上線(xiàn)項(xiàng)目的問(wèn)題
  • 可基于錯(cuò)誤捕獲,實(shí)現(xiàn)前端錯(cuò)誤監(jiān)控頁(yè),也可以用于埋點(diǎn)、數(shù)據(jù)分析等場(chǎng)景。
  • 這四種方式通常組合起來(lái)使用,會(huì)實(shí)現(xiàn)更好的效果

到此這篇關(guān)于如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式 的文章就介紹到這了,更多相關(guān)監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論