日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

一、錯誤類型

任何一個框架,對于錯誤的處理都是一種必備的能力

在Vue 中,則是定義了一套對應的錯誤處理規則給到使用者,且在源代碼級別,對部分必要的過程做了一定的錯誤處理。

主要的錯誤來源包括:

  • 后端接口錯誤
  • 代碼中本身邏輯錯誤

二、如何處理

后端接口錯誤

通過axIOS的interceptor實現網絡請求的response先進行一層攔截

apiClient.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (error.response.status == 401) {
      router.push({ name: "Login" });
    } else {
      message.error("出錯了");
      return Promise.reject(error);
    }
  }
);

 

代碼邏輯問題

全局設置錯誤處理

設置全局錯誤處理函數

Vue.config.errorHandler = function (err, vm, info) {
  // handle error
  // `info` 是 Vue 特定的錯誤信息,比如錯誤所在的生命周期鉤子
  // 只在 2.2.0+ 可用
}

errorHandler指定組件的渲染和觀察期間未捕獲錯誤的處理函數。這個處理函數被調用時,可獲取錯誤信息和 Vue 實例

不過值得注意的是,在不同Vue 版本中,該全局 API 作用的范圍會有所不同:

從 2.2.0 起,這個鉤子也會捕獲組件生命周期鉤子里的錯誤。同樣的,當這個鉤子是 undefined 時,被捕獲的錯誤會通過 console.error 輸出而避免應用崩

從 2.4.0 起,這個鉤子也會捕獲 Vue 自定義事件處理函數內部的錯誤了

從 2.6.0 起,這個鉤子也會捕獲 v-on DOM 監聽器內部拋出的錯誤。另外,如果任何被覆蓋的鉤子或處理函數返回一個 Promise 鏈 (例如 async 函數),則來自其 Promise 鏈的錯誤也會被處理

生命周期鉤子

errorCaptured是 2.5.0 新增的一個生命鉤子函數,當捕獲到一個來自子孫組件的錯誤時被調用

基本類型

(err: Error, vm: Component, info: string) => ?boolean

 

此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播

參考官網,錯誤傳播規則如下:

  • 默認情況下,如果全局的 config.errorHandler 被定義,所有的錯誤仍會發送它,因此這些錯誤仍然會向單一的分析服務的地方進行匯報
  • 如果一個組件的繼承或父級從屬鏈路中存在多個 errorCaptured 鉤子,則它們將會被相同的錯誤逐個喚起。
  • 如果此 errorCaptured 鉤子自身拋出了一個錯誤,則這個新錯誤和原本被捕獲的錯誤都會發送給全局的 config.errorHandler
  • 一個 errorCaptured 鉤子能夠返回 false 以阻止錯誤繼續向上傳播。本質上是說“這個錯誤已經被搞定了且應該被忽略”。它會阻止其它任何會被這個錯誤喚起的 errorCaptured 鉤子和全局的 config.errorHandler

下面來看個例子

定義一個父組件cat

Vue.component('cat', {
    template:`
        <div>
			<h1>Cat: </h1>
        	<slot></slot>
        </div>`,
    props:{
        name:{
            required:true,
            type:String
        }
    },
    errorCaptured(err,vm,info) {
        console.log(`cat EC: ${err.toString()}ninfo: ${info}`); 
        return false;
    }

});

 

定義一個子組件kitten,其中dontexist()并沒有定義,存在錯誤

Vue.component('kitten', {
    template:'<div><h1>Kitten: {{ dontexist() }}</h1></div>',
    props:{
        name:{
            required:true,
            type:String
        }
    }
});

 

頁面中使用組件

<div id="App" v-cloak>
    <cat name="my cat">
        <kitten></kitten>
    </cat>
</div>

在父組件的errorCaptured則能夠捕獲到信息

cat EC: TypeError: dontexist is not a function
info: render

三、源碼分析

異常處理源碼

源碼位置:/src/core/util/error.js

// Vue 全局配置,也就是上面的Vue.config
import config from '../config'
import { warn } from './debug'
// 判斷環境
import { inBrowser, inWeex } from './env'
// 判斷是否是Promise,通過val.then === 'function' && val.catch === 'function', val !=== null && val !== undefined
import { isPromise } from 'shared/util'
// 當錯誤函數處理錯誤時,停用deps跟蹤以避免可能出現的infinite rendering
// 解決以下出現的問題https://github.com/vuejs/vuex/issues/1505的問題
import { pushTarget, popTarget } from '../observer/dep'

export function handleError (err: Error, vm: any, info: string) {
    // Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
    pushTarget()
    try {
        // vm指當前報錯的組件實例
        if (vm) {
            let cur = vm
            // 首先獲取到報錯的組件,之后遞歸查找當前組件的父組件,依次調用errorCaptured 方法。
            // 在遍歷調用完所有 errorCaptured 方法、或 errorCaptured 方法有報錯時,調用 globalHandleError 方法
            while ((cur = cur.$parent)) {
                const hooks = cur.$options.errorCaptured
                // 判斷是否存在errorCaptured鉤子函數
                if (hooks) {
                    // 選項合并的策略,鉤子函數會被保存在一個數組中
                    for (let i = 0; i < hooks.length; i++) {
                        // 如果errorCaptured 鉤子執行自身拋出了錯誤,
                        // 則用try{}catch{}捕獲錯誤,將這個新錯誤和原本被捕獲的錯誤都會發送給全局的config.errorHandler
                        // 調用globalHandleError方法
                        try {
                            // 當前errorCaptured執行,根據返回是否是false值
                            // 是false,capture = true,阻止其它任何會被這個錯誤喚起的 errorCaptured 鉤子和全局的 config.errorHandler
                            // 是true capture = fale,組件的繼承或父級從屬鏈路中存在的多個 errorCaptured 鉤子,會被相同的錯誤逐個喚起
                            // 調用對應的鉤子函數,處理錯誤
                            const capture = hooks[i].call(cur, err, vm, info) === false
                            if (capture) return
                        } catch (e) {
                            globalHandleError(e, cur, 'errorCaptured hook')
                        }
                    }
                }
            }
        }
        // 除非禁止錯誤向上傳播,否則都會調用全局的錯誤處理函數
        globalHandleError(err, vm, info)
    } finally {
        popTarget()
    }
}
// 異步錯誤處理函數
export function invokeWithErrorHandling (
handler: Function,
 context: any,
 args: null | any[],
    vm: any,
        info: string
        ) {
            let res
            try {
                // 根據參數選擇不同的handle執行方式
                res = args ? handler.apply(context, args) : handler.call(context)
                // handle返回結果存在
                // res._isVue an flag to avoid this being observed,如果傳入值的_isVue為ture時(即傳入的值是Vue實例本身)不會新建observer實例
                // isPromise(res) 判斷val.then === 'function' && val.catch === 'function', val !=== null && val !== undefined
                // !res._handled  _handle是Promise 實例的內部變量之一,默認是false,代表onFulfilled,onRejected是否被處理
                if (res && !res._isVue && isPromise(res) && !res._handled) {
                    res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
                    // avoid catch triggering multiple times when nested calls
                    // 避免嵌套調用時catch多次的觸發
                    res._handled = true
                }
            } catch (e) {
                // 處理執行錯誤
                handleError(e, vm, info)
            }
            return res
        }

//全局錯誤處理
function globalHandleError (err, vm, info) {
    // 獲取全局配置,判斷是否設置處理函數,默認undefined
    // 已配置
    if (config.errorHandler) {
        // try{}catch{} 住全局錯誤處理函數
        try {
            // 執行設置的全局錯誤處理函數,handle error 想干啥就干啥
            return config.errorHandler.call(null, err, vm, info)
        } catch (e) {
            // 如果開發者在errorHandler函數中手動拋出同樣錯誤信息throw err
            // 判斷err信息是否相等,避免log兩次
            // 如果拋出新的錯誤信息throw err Error('你好毒'),將會一起log輸出
            if (e !== err) {
                logError(e, null, 'config.errorHandler')
            }
        }
    }
    // 未配置常規log輸出
    logError(err, vm, info)
}

// 錯誤輸出函數
function logError (err, vm, info) {
    if (process.env.NODE_ENV !== 'production') {
        warn(`Error in ${info}: "${err.toString()}"`, vm)
    }
    /* istanbul ignore else */
    if ((inBrowser || inWeex) && typeof console !== 'undefined') {
        console.error(err)
    } else {
        throw err
    }
}

 

小結

  • handleError在需要捕獲異常的地方調用,首先獲取到報錯的組件,之后遞歸查找當前組件的父組件,依次調用errorCaptured 方法,在遍歷調用完所有 errorCaptured 方法或 errorCaptured 方法有報錯時,調用 globalHandleError 方法
  • globalHandleError調用全局的 errorHandler 方法,再通過logError判斷環境輸出錯誤信息
  • invokeWithErrorHandling更好的處理異步錯誤信息
  • logError判斷環境,選擇不同的拋錯方式。非生產環境下,調用warn方法處理錯誤

其它錯誤

1、在配置路由并引入組件后,報錯:

    Unknown custom element: <router-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

  錯誤原因:vue-router沒有注冊

  解決辦法:

    //注冊插件 *****************非常重要,不能忘記

    Vue.use(VueRouter)

2、在組件中的標簽和樣式中圖片路徑出錯時:報錯:

    Errors while compiling. Reload prevented.

    Module not found: Error: Can't resolve '
./src/assets/img/btn_bg.png' in 'E:myStudyvue案例chexian-spasrccomponents'

  解決辦法:將圖片的路徑重新書寫

3、在組件中標簽沒有閉合,報錯:

     Errors while compiling. Reload prevented.

    
./node_modules/_vue-loader@13.4.0@vue-loader/lib/template-compiler?{"id":"data-v-00822b28","hasScoped":false,"buble":{"transforms":{}}}!./node_modules/_vue-loader@13.4.0@vue-loader/lib/selector.js?type=template&index=0&bustCache!./src/components/BaseProject.vue

(Emitted value instead of an instance of Error)

  解決辦法:檢查html代碼

4、在使用less定義變量是報錯:

前端開發中 vue項目中常見的錯誤處理

 

  錯誤原因:必須用分號結尾:@imgUrl:'../../assets/img/';

前端開發中 vue項目中常見的錯誤處理

 

Compiled with problems:

編譯問題

C:myelsrcviewsHomeView.vue

錯誤出現文件

3:1 error Mixed spaces and tabs no-mixed-spaces-and-tabs

4:1 error Mixed spaces and tabs no-mixed-spaces-and-tabs

第3行的第一個字符

第4函的第一個字符

Mixed spaces and tabs

錯誤原因:混合的空格與tab

no-mixed-spaces-and-tabs

錯誤規則: no-mixed-spaces-and-tabs 不準混空格與tab

2 problems (2 errors, 0 warnings)

2個問題(2個錯誤,0個警告)

前端開發中 vue項目中常見的錯誤處理

 

Compiled with problems:

編譯錯誤

ERROR in ./src/views/HomeView.vue?

錯誤出現的位置

Unexpected keyword 'const'. (6:0)

第6行第0個字符有個不應該出現的關鍵字 const

63 | const user = reactive({ userid: "", pwd: "", code: "" }), | ^ 64 | const rules = reactive({ | ^ 65 | userid: [

第63到64行兩個^之間有錯誤

前端開發中 vue項目中常見的錯誤處理

 

ERROR in ./src/router/index.ts 10:19-57

錯誤發生在 ./src/router/index.ts 第10行第19個字符到57字符

Module not found: Error: Can't resolve '../views/admin/AdminVeiw.vue' in 'C:myelsrcrouter'

,模塊找不的 不能resolve(兌現,發現,解決)
../views/admin/AdminVeiw.vue

在C:myelsrcrouter

總結:文件
../views/admin/AdminVeiw.vue(文件名/路徑發生錯誤)

本地開發環境請求服務器接口跨域的問題

前端開發中 vue項目中常見的錯誤處理

 

上面的這個報錯大家都不會陌生,報錯是說沒有訪問權限(跨域問題)。本地開發項目請求服務器接口的時候,因為客戶端的同源策略,導致了跨域的問題。

下面先演示一個沒有配置允許本地跨域的的情況:

前端開發中 vue項目中常見的錯誤處理

 


前端開發中 vue項目中常見的錯誤處理

 


前端開發中 vue項目中常見的錯誤處理

 

可以看到,此時我們點擊獲取數據,瀏覽器提示我們跨域了。所以我們訪問不到數據。

那么接下來我們演示設置允許跨域后的數據獲取情況:

前端開發中 vue項目中常見的錯誤處理

 

注意:配置好后一定要關閉原來的server,重新npm run dev啟動項目。不然無效。

前端開發中 vue項目中常見的錯誤處理

 


前端開發中 vue項目中常見的錯誤處理

 

注意:配置好后一定要關閉原來的server,重新npm run dev啟動項目。不然無效。

我們在1出設置了允許本地跨域,在2處,要注意我們訪問接口時,寫的是/api,此處的/api指代的就是我們要請求的接口域名。如果我們不想每次接口都帶上/api,可以更改axios的默認配置axios.defaults.baseURL = '/api';這樣,我們請求接口就可以直接this.$axios.get('app.php?m=App&c=Index&a=index'),很簡單有木有。此時如果你在network中查看xhr請求,你會發現顯示的是localhost:8080/api的請求地址。這樣沒什么大驚小怪的,代理而已:

前端開發中 vue項目中常見的錯誤處理

 

給大家分享我收集整理的各種學習資料,前端小白交流、學習交流,也可以直接問我,我會組織大家一起做項目練習,幫助大家匹配一位學習伙伴互相監督學習-下面是學習資料參考。

分享到:
標簽:vue
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定