vue-router導(dǎo)航守衛(wèi)之實戰(zhàn)篇

1.導(dǎo)航守衛(wèi)是什么

官方這么說:

正如其名以故,*vue-router*提供的導(dǎo)航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。

好吧,看不懂胸私,就好(當(dāng))好(廢)理(話)解(吧)下。其實煤傍,導(dǎo)航守衛(wèi)就是路由跳轉(zhuǎn)過程中的一些鉤子函數(shù)盖文,再直白點路由跳轉(zhuǎn)是一個大的過程嘱蛋,這個大的過程分為跳轉(zhuǎn)前中后等等細(xì)小的過程蚯姆,在每一個過程中都有一函數(shù),這個函數(shù)能讓你操作一些其他的事兒的時機(jī)洒敏,這就是導(dǎo)航守衛(wèi)龄恋。

2.導(dǎo)航守衛(wèi)全解析

先看一個鉤子函數(shù)執(zhí)行后輸出的順序截圖吧,一般講解都會在之后呈現(xiàn)凶伙,給大家換種思路(也就是先預(yù)習(xí)再學(xué)習(xí)最后復(fù)習(xí))

[圖片上傳失敗...(image-b044c6-1632499247491)]

好吧不知道的估計看不懂吧郭毕!不過我希望你能看到一個點能多倒回來看看這個順序,前方干貨預(yù)警


導(dǎo)航守衛(wèi)分為:全局的函荣、單個路由獨享的显押、組件內(nèi)的三種。分別來看一下:

【全局的】:是指路由實例上直接操作的鉤子函數(shù)傻挂,他的特點是所有路由配置的組件都會觸發(fā)乘碑,直白點就是觸發(fā)路由就會觸發(fā)這些鉤子函數(shù),如下的寫法金拒。鉤子函數(shù)按執(zhí)行順序包括beforeEach兽肤、beforeResolve(2.5+)、afterEach三個(以下的鉤子函數(shù)都是按執(zhí)行順序講解的):

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

[beforeEach]:在路由跳轉(zhuǎn)前觸發(fā),參數(shù)包括to,from,next(參數(shù)會單獨介紹)三個资铡,這個鉤子作用主要是用于登錄驗證电禀,也就是路由還沒跳轉(zhuǎn)提前告知,以免跳轉(zhuǎn)了再通知就為時已晚笤休。

[beforeResolve](2.5+):這個鉤子和beforeEach類似尖飞,也是路由跳轉(zhuǎn)前觸發(fā),參數(shù)也是to,from,next三個宛官,和beforeEach區(qū)別官方解釋為:

區(qū)別是在導(dǎo)航被確認(rèn)之前葫松,同時在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,解析守衛(wèi)就被調(diào)用底洗。

即在 beforeEach 和 組件內(nèi)beforeRouteEnter 之后腋么,afterEach之前調(diào)用。

[afterEach]:和beforeEach相反亥揖,他是在路由跳轉(zhuǎn)完成后觸發(fā)珊擂,參數(shù)包括to,from沒有了next(參數(shù)會單獨介紹),他發(fā)生在beforeEach和beforeResolve之后,beforeRouteEnter(組件內(nèi)守衛(wèi)费变,后講)之前摧扇。

【路由獨享的】是指在單個路由配置的時候也可以設(shè)置的鉤子函數(shù),其位置就是下面示例中的位置挚歧,也就是像Foo這樣的組件都存在這樣的鉤子函數(shù)扛稽。目前他只有一個鉤子函數(shù)beforeEnter:

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

[beforeEnter]:和beforeEach完全相同,如果都設(shè)置則在beforeEach之后緊隨執(zhí)行滑负,參數(shù)to在张、from、next

【組件內(nèi)的】:是指在組件內(nèi)執(zhí)行的鉤子函數(shù)矮慕,類似于組件內(nèi)的生命周期帮匾,相當(dāng)于為配置路由的組件添加的生命周期鉤子函數(shù)。鉤子函數(shù)按執(zhí)行順序包括beforeRouteEnter痴鳄、beforeRouteUpdate (2.2+)瘟斜、beforeRouteLeave三個,執(zhí)行位置如下:

<template>
  ...
</template>
export default{
  data(){
    //...
  },
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
    // 不痪寻!能螺句!獲取組件實例 `this`
    // 因為當(dāng)守衛(wèi)執(zhí)行前,組件實例還沒被創(chuàng)建
  },
  beforeRouteUpdate (to, from, next) {
    // 在當(dāng)前路由改變橡类,但是該組件被復(fù)用時調(diào)用
    // 舉例來說蛇尚,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時候猫态,
    // 由于會渲染同樣的 Foo 組件佣蓉,因此組件實例會被復(fù)用披摄。而這個鉤子就會在這個情況下被調(diào)用。
    // 可以訪問組件實例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用
    // 可以訪問組件實例 `this`
  }
}
<style>
  ...
</style>

[beforeRouteEnter]:路由進(jìn)入之前調(diào)用勇凭,參數(shù)包括to疚膊,from,next虾标。該鉤子在全局守衛(wèi)beforeEach和獨享守衛(wèi)beforeEnter之后寓盗,全局beforeResolve和全局afterEach之前調(diào)用,要注意的是該守衛(wèi)內(nèi)訪問不到組件的實例璧函,也就是this為undefined傀蚌,也就是他在beforeCreate生命周期前觸發(fā)。在這個鉤子函數(shù)中蘸吓,可以通過傳一個回調(diào)給 next來訪問組件實例善炫。在導(dǎo)航被確認(rèn)的時候執(zhí)行回調(diào),并且把組件實例作為回調(diào)方法的參數(shù)库继,可以在這個守衛(wèi)中請求服務(wù)端獲取數(shù)據(jù)箩艺,當(dāng)成功獲取并能進(jìn)入路由時,調(diào)用next并在回調(diào)中通過 vm訪問組件實例進(jìn)行賦值等操作宪萄,(next中函數(shù)的調(diào)用在mounted之后:為了確保能對組件實例的完整訪問)艺谆。

 beforeRouteEnter (to, from, next) {
  // 這里還無法訪問到組件實例,this === undefined
  next( vm => {
    // 通過 `vm` 訪問組件實例
  })
}

[beforeRouteUpdate] (v 2.2+):在當(dāng)前路由改變時拜英,并且該組件被復(fù)用時調(diào)用静汤,可以通過this訪問實例。參數(shù)包括to居凶,from虫给,next∨偶啵可能有的同學(xué)會疑問狰右,what is 路由改變 or what is 組件被復(fù)用杰捂?

  • 對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id舆床,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時候,組件實例會被復(fù)用嫁佳,該守衛(wèi)會被調(diào)用
  • 當(dāng)前路由query變更時挨队,該守衛(wèi)會被調(diào)用

[beforeRouteLeave]:導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用,可以訪問組件實例this蒿往,參數(shù)包括to盛垦,from,next瓤漏。

至此腾夯,所有鉤子函數(shù)介紹完畢颊埃。

屢一下哈:

全局路由鉤子:beforeEach(to,from, next)、beforeResolve(to,from, next)蝶俱、afterEach(to,from)班利;

獨享路由鉤子:beforeEnter(to,from, next);

組件內(nèi)路由鉤子:beforeRouteEnter(to,from, next)榨呆、beforeRouteUpdate(to,from, next)罗标、beforeRouteLeave(to,from, next)

不知道你是否還記得to、from积蜻、next這三個參數(shù)

下面請重頭把這幾個鉤子函數(shù)的參數(shù)看一遍闯割,細(xì)心的同學(xué)可以看見在afterEach鉤子中參數(shù)沒有next,為什么呢竿拆?

3.導(dǎo)航守衛(wèi)回調(diào)參數(shù)

to:目標(biāo)路由對象宙拉;

from:即將要離開的路由對象;

next:他是最重要的一個參數(shù)丙笋,他相當(dāng)于佛珠的線鼓黔,把一個一個珠子逐個串起來。以下注意點務(wù)必牢記:

1.但凡涉及到有next參數(shù)的鉤子不见,必須調(diào)用next() 才能繼續(xù)往下執(zhí)行下一個鉤子澳化,否則路由跳轉(zhuǎn)等會停止。

2.如果要中斷當(dāng)前的導(dǎo)航要調(diào)用next(false)稳吮。如果瀏覽器的 URL 改變了 (可能是用戶手動或者瀏覽器后退按鈕)缎谷,那么 URL 地址會重置到from路由對應(yīng)的地址。(主要用于登錄驗證不通過的處理)

3.當(dāng)然next可以這樣使用灶似,next('/') 或者 next({ path: '/' }): 跳轉(zhuǎn)到一個不同的地址列林。意思是當(dāng)前的導(dǎo)航被中斷,然后進(jìn)行一個新的導(dǎo)航酪惭∠3眨可傳遞的參數(shù)與router.push中選項一致。

4.在beforeRouteEnter鉤子中next((vm)=>{})內(nèi)接收的回調(diào)函數(shù)參數(shù)為當(dāng)前組件的實例vm春感,這個回調(diào)函數(shù)在生命周期mounted之后調(diào)用砌创,也就是,他是所有導(dǎo)航守衛(wèi)和生命周期函數(shù)最后執(zhí)行的那個鉤子鲫懒。

5.next(error): (v2.4.0+) 如果傳入 next 的參數(shù)是一個 Error 實例嫩实,則導(dǎo)航會被終止且該錯誤會被傳遞給 [router.onError()](https://link.zhihu.com/?target=https%3A//router.vuejs.org/zh-cn/api/router-instance.html%23%25E6%2596%25B9%25E6%25B3%2595) 注冊過的回調(diào)。

4.總結(jié)

好了窥岩,還記得那個截圖嗎甲献,我們再看一遍

[圖片上傳失敗...(image-940ea2-1632499247491)]

我們最后屢一下順序:

當(dāng)點擊切換路由時:beforeRouterLeave-->beforeEach-->beforeEnter-->beforeRouteEnter-->beforeResolve-->afterEach-->beforeCreate-->created-->beforeMount-->mounted-->beforeRouteEnter的next的回調(diào)

當(dāng)路由更新時:beforeRouteUpdate

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颂翼,隨后出現(xiàn)的幾起案子晃洒,更是在濱河造成了極大的恐慌慨灭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件球及,死亡現(xiàn)場離奇詭異缘挑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)桶略,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門语淘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人际歼,你說我怎么就攤上這事惶翻。” “怎么了鹅心?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵吕粗,是天一觀的道長。 經(jīng)常有香客問我旭愧,道長颅筋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任输枯,我火速辦了婚禮议泵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桃熄。我一直安慰自己先口,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布瞳收。 她就那樣靜靜地躺著碉京,像睡著了一般。 火紅的嫁衣襯著肌膚如雪螟深。 梳的紋絲不亂的頭發(fā)上谐宙,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機(jī)與錄音界弧,去河邊找鬼凡蜻。 笑死,一個胖子當(dāng)著我的面吹牛夹纫,可吹牛的內(nèi)容都是我干的咽瓷。 我是一名探鬼主播设凹,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼舰讹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闪朱?” 一聲冷哼從身側(cè)響起月匣,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钻洒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锄开,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體素标,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年萍悴,在試婚紗的時候發(fā)現(xiàn)自己被綠了头遭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡癣诱,死狀恐怖计维,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情撕予,我是刑警寧澤鲫惶,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站实抡,受9級特大地震影響欠母,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吆寨,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一赏淌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啄清,春花似錦猜敢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至添寺,卻和暖如春胯盯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背计露。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工博脑, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人票罐。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓叉趣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親该押。 傳聞我的和親對象是個殘疾皇子疗杉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容