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

深入理解Vue 的鉤子函數(shù)

 更新時間:2018年09月05日 11:09:14   投稿:mrr  
這篇文章主要介紹了Vue 的鉤子函數(shù),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

前言

說到Vue的鉤子函數(shù),可能很多人只停留在一些很簡單常用的鉤子( created , mounted ),而且對于里面的區(qū)別,什么時候該用什么鉤子,并沒有仔細的去研究過,且Vue的生命周期在面試中也算是比較高頻的考點,那么該如何回答這類問題,讓人有眼前一亮的感覺呢...

Vue-Router導航守衛(wèi)

有的時候,我們需要通過路由來進行一些操作,比如最常見的登錄權(quán)限驗證,當用戶滿足條件時,才讓其進入導航,否則就取消跳轉(zhuǎn),并跳到登錄頁面讓其登錄。

為此我們有很多種方法可以植入路由的導航過程: 全局的, 單個路由獨享的, 或者組件級的 , 推薦優(yōu)先閱讀官方路由文檔

全局守衛(wèi)

vue-router全局有三個守衛(wèi):

  1. router.beforeEach 全局前置守衛(wèi) 進入路由之前
  2. router.beforeResolve 全局解析守衛(wèi)(2.5.0+) 在beforeRouteEnter調(diào)用之后調(diào)用
  3. router.afterEach 全局后置鉤子 進入路由之后

使用方法:

// main.js 入口文件
import router from './router' ; // 引入路由
router . beforeEach (( to , from , next ) => {
next ();
});
router . beforeResolve (( to , from , next ) => {
next ();
});
router . afterEach (( to , from ) => {
console . log ( 'afterEach 全局后置鉤子' );
});

to,from,next 這三個參數(shù):

to和from是 將要進入和將要離開的路由對象 ,路由對象指的是平時通過this.$route獲取到的路由對象。

next:Function這個參數(shù)是個函數(shù),且 必須調(diào)用,否則不能進入路由 (頁面空白)。

  • next() 進入該路由。
  • next(false): 取消進入路由,url地址重置為from路由地址(也就是將要離開的路由地址)。
  • next 跳轉(zhuǎn)新路由,當前的導航被中斷,重新開始一個新的導航。

我們可以這樣跳轉(zhuǎn):next('path地址') 或者 next({path:''}) 或者 next({name:''}) 且允許設置諸如 replace: true、name: 'home' 之類的選項 以及你用在router-link或router.push的對象選項。

路由獨享守衛(wèi)

如果你不想全局配置守衛(wèi)的話,你可以為某些路由單獨配置守衛(wèi):

const router = new VueRouter({
routes : [
{
path : '/foo' ,
component : Foo ,
beforeEnter : ( to , from , next ) => {
// ...
}
}
]
})

路由組件內(nèi)的守衛(wèi):

  1. beforeRouteEnter 進入路由前
  2. beforeRouteUpdate (2.2) 路由復用同一個組件時
  3. beforeRouteLeave 離開當前路由時

文檔中的介紹:

beforeRouteEnter (to, from, next) {
},
beforeRouteUpdate ( to , from , next ) {
// 在當前路由改變,但是該組件被復用時調(diào)用 可以訪問組件實例 `this`
},
beforeRouteLeave ( to , from , next ) {
// 導航離開該組件的對應路由時調(diào)用,可以訪問組件實例 `this`
}

beforeRouteEnter訪問this

因為鉤子在組件實例還沒被創(chuàng)建的時候調(diào)用,所以不能獲取組件實例 this ,可以通過傳一個回調(diào)給 next 來訪問組件實例 。

但是 回調(diào)的執(zhí)行時機在mounted后面 ,所以在我看來這里對this的訪問意義不太大,可以放在 created 或者 mounted 里面。

beforeRouteEnter (to, from, next) {
console . log ( '在路由獨享守衛(wèi)后調(diào)用' );
next ( vm => {
// 通過 `vm` 訪問組件實例`this` 執(zhí)行回調(diào)的時機在mounted后面,
})
}

beforeRouteLeave:

導航離開該組件的對應路由時調(diào)用,我們用它來禁止用戶離開,比如還未保存草稿,或者在用戶離開前,將 setInterval 銷毀,防止離開之后,定時器還在調(diào)用。

beforeRouteLeave (to, from , next) {
if ( 文章保存 ) {
next (); // 允許離開或者可以跳到別的路由 上面講過了
} else {
next ( false ); // 取消離開
}
}

關(guān)于鉤子的一些知識:

路由鉤子函數(shù)的錯誤捕獲

如果我們在全局守衛(wèi)/路由獨享守衛(wèi)/組件路由守衛(wèi)的鉤子函數(shù)中有錯誤,可以這樣捕獲:

router.onError(callback => {
// 2.4.0新增 并不常用,了解一下就可以了
console . log ( callback , 'callback' );
});

在路由文檔中還有更多的實例方法:動態(tài)添加路由等,有興趣可以了解一下。

跳轉(zhuǎn)死循環(huán),頁面永遠空白

我了解到的,很多人會碰到這個問題,來看一下這段偽代碼:

router.beforeEach((to, from, next) => {
if ( 登錄 ){
next ()
} else {
next ({ name : 'login' });
}
});

看邏輯貌似是對的,但是當我們跳轉(zhuǎn)到 login 之后,因為此時還是未登錄狀態(tài),所以會一直跳轉(zhuǎn)到 login 然后死循環(huán),頁面一直是空白的,所以:我們需要把判斷條件稍微改一下。

if(登錄 || to.name === 'login'){ next() } // 登錄,或者將要前往login頁面的時候,就允許進入路由
全局后置鉤子的跳轉(zhuǎn):

文檔中提到因為router.afterEach不接受 next 函數(shù)所以也不會改變導航本身,意思就是只能當成一個鉤子來使用,但是我自己在試的時候發(fā)現(xiàn),我們可以通過這種形式來實現(xiàn)跳轉(zhuǎn):

// main.js 入口文件
import router from './router' ; // 引入路由
router . afterEach (( to , from ) => {
if ( 未登錄 && to . name !== 'login' ) {
router . push ({ name : 'login' }); // 跳轉(zhuǎn)login
}
});

額,通過router.beforeEach 也完全可以實現(xiàn)且更好,我就騷一下。

完整的路由導航解析流程(不包括其他生命周期):

  1. 觸發(fā)進入其他路由。
  2. 調(diào)用要離開路由的組件守衛(wèi) beforeRouteLeave
  3. 調(diào)用局前置守衛(wèi): beforeEach
  4. 在重用的組件里調(diào)用 beforeRouteUpdate
  5. 調(diào)用路由獨享守衛(wèi) beforeEnter 。
  6. 解析異步路由組件。
  7. 在將要進入的路由組件中調(diào)用 beforeRouteEnter
  8. 調(diào)用全局解析守衛(wèi) beforeResolve
  9. 導航被確認。
  10. 調(diào)用全局后置鉤子的 afterEach 鉤子。
  11. 觸發(fā)DOM更新( mounted )。
  12. 執(zhí)行 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)

你不知道的keep-alive[我猜你不知道]

在開發(fā)Vue項目的時候,大部分組件是沒必要多次渲染的,所以Vue提供了一個內(nèi)置組件 keep-alive 來 緩存組件內(nèi)部狀態(tài),避免重新渲染 。

文檔:和 <transition> 相似, <keep-alive> 是一個抽象組件:它自身不會渲染一個 DOM 元素,也不會出現(xiàn)在父組件鏈中。

用法:

緩存動態(tài)組件:

<keep-alive> 包裹動態(tài)組件時,會緩存不活動的組件實例,而不是銷毀它們,此種方式并無太大的實用意義。

<!-- 基本 -->
< keep - alive >
< component : is = "view" ></ component >
</ keep - alive >
<!-- 多個條件判斷的子組件 -->
< keep - alive >
< comp - a v - if = "a > 1" ></ comp - a >
< comp - b v - else ></ comp - b >
</ keep - alive >

緩存路由組件:

使用 keep-alive 可以將所有路徑匹配到的路由組件都緩存起來,包括路由組件里面的組件, keep-alive 大多數(shù)使用場景就是這種。

<keep-alive>
< router - view ></ router - view >
</ keep - alive >

生命周期鉤子:

這篇既然是Vue鉤子函數(shù)的專場,那肯定要扣題呀~

在被 keep-alive 包含的組件/路由中,會多出兩個生命周期的鉤子: activated 與 deactivated 。

文檔:在 2.2.0 及其更高版本中,activated 和 deactivated 將會在 樹內(nèi)的 所有嵌套組件 中觸發(fā)。

activated 在組件第一次渲染時會被調(diào)用,之后在每次緩存組件被激活時調(diào)用。

activated調(diào)用時機:

第一次進入緩存路由/組件,在 mounted 后面, beforeRouteEnter 守衛(wèi)傳給 next 的回調(diào)函數(shù)之前調(diào)用:

beforeMount=> 如果你是從別的路由/組件進來(組件銷毀destroyed/或離開緩存deactivated)=>
mounted=> activated 進入緩存組件 => 執(zhí)行 beforeRouteEnter回調(diào)

因為組件被緩存了,再次進入緩存路由/組件時,不會觸發(fā)這些鉤子:

beforeCreate created beforeMount mounted 都不會觸發(fā)。

所以之后的調(diào)用時機是:

組件銷毀destroyed/或離開緩存deactivated => activated 進入當前緩存組件

=> 執(zhí)行 beforeRouteEnter回調(diào)

組件緩存或銷毀,嵌套組件的銷毀和緩存也在這里觸發(fā)

deactivated:組件被停用(離開路由)時調(diào)用

使用了keep-alive就不會調(diào)用beforeDestroy(組件銷毀前鉤子)和destroyed(組件銷毀),因為組件沒被銷毀,被緩存起來了。

這個鉤子可以看作 beforeDestroy 的替代,如果你緩存了組件,要在組件銷毀的的時候做一些事情,你可以放在這個鉤子里。

如果你離開了路由,會依次觸發(fā):

組件內(nèi)的離開當前路由鉤子beforeRouteLeave =>  路由前置守衛(wèi) beforeEach =>

全局后置鉤子afterEach => deactivated 離開緩存組件 => activated 進入緩存組件(如果你進入的也等于是緩存路由)

如果離開的組件沒有緩存的話 beforeDestroy會替換deactivated

如果進入的路由也沒有緩存的話  全局后置鉤子afterEach=>銷毀 destroyed=> beforeCreate等

那么,如果我只是想緩存其中幾個路由/組件,那該怎么做?

緩存你想緩存的路由:

Vue2.1.0之前:

想實現(xiàn)類似的操作,你可以:

  1. 配置一下路由元信息
  2. 創(chuàng)建兩個 keep-alive 標簽
  3. 使用 v-if 通過路由元信息判斷緩存哪些路由。
<keep-alive>
< router - view v - if = "$route.meta.keepAlive" >
<!-- 這里是會被緩存的路由 -->
</ router - view >
</ keep - alive >
< router - view v - if = "!$route.meta.keepAlive" >
<!-- 因為用的是v - if 所以下面還要創(chuàng)建一個未緩存的路由視圖出口 -->
</ router - view >
//router配置
new Router ({
routes : [
{
path : '/' ,
name : 'home' ,
component : Home ,
meta : {
keepAlive : true // 需要被緩存
}
},
{
path : '/:id' ,
name : 'edit' ,
component : Edit ,
meta : {
keepAlive : false // 不需要被緩存
}
}
]
});

Vue2.1.0版本之后:

使用路由元信息的方式,要多創(chuàng)建一個 router-view 標簽,并且每個路由都要配置一個元信息,是可以實現(xiàn)我們想要的效果,但是過于繁瑣了點。

幸運的是在Vue2.1.0之后,Vue新增了兩個屬性配合 keep-alive 來有條件地緩存 路由/組件。

新增屬性:

  • include :匹配的 路由/組件 會被緩存
  • exclude :匹配的 路由/組件 不會被緩存

include 和 exclude 支持三種方式來有條件的緩存路由:采用逗號分隔的字符串形式,正則形式,數(shù)組形式。

正則和數(shù)組形式,必須采用 v-bind 形式來使用。

緩存組件的使用方式:

<!-- 逗號分隔字符串 -->
< keep - alive include = "a,b" >
< component : is = "view" ></ component >
</ keep - alive >
<!-- 正則表達式 ( 使用 `v-bind` ) -->
< keep - alive : include = "/a|b/" >
< component : is = "view" ></ component >
</ keep - alive >
<!-- 數(shù)組 ( 使用 `v-bind` ) -->
< keep - alive : include = "['a', 'b']" >
< component : is = "view" ></ component >
</ keep - alive >

但更多場景中,我們會使用keep-alive來緩存路由:

<keep-alive include='a'>
< router - view ></ router - view >
</ keep - alive >

匹配規(guī)則:

  1. 首先匹配組件的name選項,如果 name 選項不可用。
  2. 則匹配它的 局部注冊名稱 。 (父組件 components 選項的鍵值)
  3. 匿名組件,不可匹配。

比如路由組件沒有 name 選項,并且沒有注冊的組件名。

只能匹配當前被包裹的組件, 不能匹配更下面嵌套的子組件 。

比如用在路由上,只能匹配路由組件的 name 選項,不能匹配路由組件里面的嵌套組件的 name 選項。

文檔: <keep-alive> 不會在函數(shù)式組件中正常工作 ,因為它們沒有緩存實例。

exclude 的優(yōu)先級大于 include

也就是說:當 include 和 exclude 同時存在時, exclude 生效, include 不生效。

<keep-alive include="a,b" exclude="a">
<!-- 只有a不被緩存 -->
< router - view ></ router - view >
</ keep - alive >

當組件被exclude匹配,該組件將不會被緩存,不會調(diào)用activated 和 deactivated。

組件生命周期鉤子:

關(guān)于組件的生命周期,是時候放出這張圖片了:


這張圖片已經(jīng)講得很清楚了,很多人這部分也很清楚了,大部分生命周期并不會用到,這里提一下幾點:

  1. ajax請求最好放在 created 里面 ,因為此時已經(jīng)可以訪問 this 了,請求到數(shù)據(jù)就可以直接放在 data 里面。
  2. 這里也碰到過幾次,面試官問:ajax請求應該放在哪個生命周期。
  3. 關(guān)于dom的操作要放在 mounted 里面 ,在 mounted 前面訪問dom會是 undefined 。
  4. 每次進入/離開組件都要做一些事情,用什么鉤子:

不緩存:

進入的時候可以用 created 和 mounted 鉤子,離開的時候用 beforeDestory 和 destroyed 鉤子, beforeDestory 可以訪問 this , destroyed 不可以訪問 this 。

緩存了組件:

緩存了組件之后,再次進入組件不會觸發(fā) beforeCreate 、 created 、 beforeMount 、 mounted , 如果你想每次進入組件都做一些事情的話,你可以放在 activated 進入緩存組件的鉤子中 。

同理:離開緩存組件的時候, beforeDestroy 和 destroyed 并不會觸發(fā),可以使用 deactivated 離開緩存組件的鉤子來代替。

觸發(fā)鉤子的完整順序:

將路由導航、 keep-alive 、和組件生命周期鉤子結(jié)合起來的,觸發(fā)順序,假設是從a組件離開,第一次進入b組件:

  1. beforeRouteLeave :路由組件的組件離開路由前鉤子,可取消路由離開。
  2. beforeEach : 路由全局前置守衛(wèi),可用于登錄驗證、全局路由loading等。
  3. beforeEnter : 路由獨享守衛(wèi)
  4. beforeRouteEnter : 路由組件的組件進入路由前鉤子。
  5. beforeResolve : 路由全局解析守衛(wèi)
  6. afterEach :路由全局后置鉤子
  7. beforeCreate :組件生命周期,不能訪問 this 。
  8. created :組件生命周期,可以訪問 this ,不能訪問dom。
  9. beforeMount :組件生命周期
  10. deactivated : 離開緩存組件a,或者觸發(fā)a的 beforeDestroy 和 destroyed 組件銷毀鉤子。
  11. mounted :訪問/操作dom。
  12. activated :進入緩存組件,進入a的嵌套子組件(如果有的話)。
  13. 執(zhí)行beforeRouteEnter回調(diào)函數(shù)next。

結(jié)語

Vue提供了很多鉤子,但很多鉤子我們幾乎不會用到,只有清楚這些鉤子函數(shù)的觸發(fā)順序以及背后的一些限制等,這樣我們才能夠正確的使用這些鉤子,希望看了本文的同學,能對這些鉤子有更加清晰的認識,使用起來更加得心應手。

總結(jié)

以上所述是小編給大家介紹的Vue 的鉤子函數(shù),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • v-for中動態(tài)校驗el-form表單項的實踐

    v-for中動態(tài)校驗el-form表單項的實踐

    在項目開發(fā)中,我們經(jīng)常會遇到表單保存的功能,本文主要介紹了v-for中動態(tài)校驗el-form表單項的實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧<BR>
    2022-05-05
  • vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法

    vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法

    在父組件 App.vue 中引用子組件 A.vue,把 name 的值傳給 A 組件。這篇文章主要介紹了vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法,需要的朋友可以參考下
    2018-01-01
  • 一文詳解vue-router中的導航守衛(wèi)

    一文詳解vue-router中的導航守衛(wèi)

    vue-router提供的導航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導航,在 vue-router 中,導航守衛(wèi)是一種非常重要的功能,所以本文將詳細講解一下vue-router中的導航守衛(wèi),感興趣的同學跟著小編一起來看看吧
    2023-07-07
  • 解決vue2中使用axios http請求出現(xiàn)的問題

    解決vue2中使用axios http請求出現(xiàn)的問題

    下面小編就為大家分享一篇解決vue2中使用axios http請求出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Vue中插槽slot的使用方法

    Vue中插槽slot的使用方法

    插槽就是子組件中的提供給父組件使用的一個占位符,用<slot></slot> 表示,父組件可以在這個占位符中填充任何模板代碼,如 HTML、組件等,填充的內(nèi)容會替換子組件的<slot></slot>標簽,這篇文章主要介紹了Vue插槽的理解和使用,需要的朋友可以參考下
    2023-03-03
  • Vue渲染器如何對節(jié)點進行掛載和更新

    Vue渲染器如何對節(jié)點進行掛載和更新

    這篇文章主要介紹了Vue 的渲染器是如何對節(jié)點進行掛載和更新的,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05
  • 詳談vue+webpack解決css引用圖片打包后找不到資源文件的問題

    詳談vue+webpack解決css引用圖片打包后找不到資源文件的問題

    下面小編就為大家分享一篇詳談vue+webpack解決css引用圖片打包后找不到資源文件的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Vue2.0生命周期的理解

    Vue2.0生命周期的理解

    這篇文章主要為大家介紹了Vue2.0生命周期,思考與理解“el被新創(chuàng)建的vm.$el替換”這句話,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Vue 框架之動態(tài)綁定 css 樣式實例分析

    Vue 框架之動態(tài)綁定 css 樣式實例分析

    這篇文章主要介紹了Vue 框架之動態(tài)綁定 css 樣式的方法,本文通過分享小實例給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-11-11
  • Vue實現(xiàn)雙向綁定的原理以及響應式數(shù)據(jù)的方法

    Vue實現(xiàn)雙向綁定的原理以及響應式數(shù)據(jù)的方法

    這篇文章主要介紹了Vue實現(xiàn)雙向綁定的原理以及響應式數(shù)據(jù)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07

最新評論