Vue.js進(jìn)階系列(37)--全局導(dǎo)航守衛(wèi)

??好了,告訴大家一個(gè)好消息,十分負(fù)責(zé)任的小編滿血復(fù)活了~哈哈哈,因?yàn)樗艘粋€(gè)好覺(jué)。那么下面讓我們一起看看今天的進(jìn)階系列吧ヽ( ̄ω ̄( ̄ω ̄〃)ゝ


image.png

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

??我們?nèi)粘I钪械膶?dǎo)航相信大家都用過(guò)吧O(∩_∩)O哈哈~。就是有指導(dǎo)你從A地到B地的路線。
??而導(dǎo)航守衛(wèi)也是同樣的道理。主要是監(jiān)聽(tīng)路由跳轉(zhuǎn)的過(guò)程。如果不太明白小編提出一個(gè)需求。比如:

image.png

??我們都知道HTML中有上圖這么一個(gè)標(biāo)題。小編的需求是當(dāng)用戶點(diǎn)擊“首頁(yè)”,標(biāo)題就變成“首頁(yè)”;當(dāng)用戶點(diǎn)擊“關(guān)于”,標(biāo)題就變成“關(guān)于”。目前有兩種實(shí)現(xiàn)的辦法,下面我們分別來(lái)看看這兩種辦法是如何實(shí)現(xiàn)的。

① 生命函數(shù)

??目前我們常用的生命函數(shù)主要有三大類(lèi),分別是:created、mounted、updated。
created:是在組件被創(chuàng)建的時(shí)候會(huì)回調(diào)的函數(shù),然后執(zhí)行該函數(shù)內(nèi)的內(nèi)容;
mounted:當(dāng)組件的模板被掛載到DOM上時(shí)就會(huì)回調(diào)該函數(shù),執(zhí)行函數(shù)內(nèi)相關(guān)的操作;
updated:只要頁(yè)面發(fā)生刷新的時(shí)候就會(huì)回調(diào)該函數(shù)從而執(zhí)行函數(shù)內(nèi)的代碼塊。
對(duì)于上面的需求,可以使用 created 函數(shù)來(lái)實(shí)現(xiàn)。具體代碼見(jiàn)下:

<script>
    export default {
        name:'home',
        created(){
            document.title="首頁(yè)"
        }
    }
</script>

??在 home.vue 頁(yè)面中添加 created 函數(shù),當(dāng)組件 home 創(chuàng)建的時(shí)候就將標(biāo)題修改成 “首頁(yè)”。其余的 “用戶” 頁(yè)面、“關(guān)于”頁(yè)面、“檔案”頁(yè)面也是以此類(lèi)推,小編就不一一展示出來(lái)啦,下面讓我們一起來(lái)看看效果:

切換標(biāo)題.gif

??但是該方法不足的地方就是:太繁瑣啦!我只是想根據(jù)導(dǎo)航欄然后修改標(biāo)題,你就在四個(gè)頁(yè)面都添加了 created 函數(shù) ??? 如果有一百個(gè)頁(yè)面你也這么修改的話,小編不會(huì)攔著你的,畢竟你十分的“勤奮” ,像小編這么“懶”的人肯定不會(huì)用這個(gè)方法的,不信你看下面就知道了 o( ̄︶ ̄)o

image.png

2.導(dǎo)航守衛(wèi)使用

??在文章的開(kāi)頭小編就說(shuō)過(guò),導(dǎo)航守衛(wèi)就是監(jiān)聽(tīng)路由的跳轉(zhuǎn)。所以使用的使用分成以下兩步:
第一:使用 beforeEach 確定跳轉(zhuǎn)變化
第二:使用 meta 確定路由跳轉(zhuǎn)變化時(shí)要修改的內(nèi)容
下面小編就告訴大家導(dǎo)航守衛(wèi)究竟怎么個(gè)導(dǎo)航發(fā) (????)

① 使用 beforeEach 確定跳轉(zhuǎn)變化

??首先在 router 中有個(gè)叫 beforeEach 的函數(shù),當(dāng)我們查看源碼時(shí)會(huì)發(fā)現(xiàn)它需要傳入一個(gè)叫 guard 的 NavigationGuard 參數(shù)

源碼.png

NavigationGuard(⊙_⊙)? 是啥?不懂,接下來(lái)我們?cè)龠M(jìn)一步看看 NavigationGuard是什么東西
image.png

??可以看到 NavigationGuard 是一個(gè)名字叫做 any 的箭頭函數(shù),箭頭函數(shù)內(nèi)部傳入了三個(gè)參數(shù):to、from、next。to代表路由即將要跳轉(zhuǎn)的地方,from代表從那個(gè)地方跳轉(zhuǎn),next 代表下一步。
??簡(jiǎn)單的說(shuō),from是從哪里來(lái),to是要到哪里去,next是下一步要怎么走。是不是通俗易懂了好多嘞~
因此根據(jù)上面的知識(shí),我們的代碼可以編寫(xiě)成如下:

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

這里,將 beforeEach 的參數(shù)寫(xiě)成箭頭函數(shù)的形式,接下來(lái)就是添加函數(shù)內(nèi)部的代碼。
??傳入的參數(shù)肯定是要用起來(lái)的,就像別人給你的零食要盡早吃,否則就過(guò)期來(lái)一樣。所以我們要在箭頭函數(shù)中使用 上面?zhèn)魅氲膮?shù),具體如下:

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

??next()參數(shù)一定要記得調(diào)用,很簡(jiǎn)單的道理,如果你不知道下一步,那你怎么繼續(xù)走下去呢 (`へ′*)ノ 緊接著是to?;仡櫳厦娴男【幪岢龅男枨?,我們要根據(jù)跳轉(zhuǎn)到的頁(yè)面修改標(biāo)題,所以通過(guò) to.title 來(lái)獲取要跳轉(zhuǎn)的頁(yè)面的標(biāo)題,將標(biāo)題賦值給document.title。
??上面呢,就是使用 beforeEach 確定跳轉(zhuǎn)變化的具體代碼。但是我們還有個(gè)地方不知道具體的數(shù)值,你猜是誰(shuí)?沒(méi)錯(cuò),我聽(tīng)到了,就是 to.title O(∩_∩)O這就是小編要講的第二個(gè)步驟。

② 使用 meta 確定跳轉(zhuǎn)變化的內(nèi)容

其實(shí)meta 很簡(jiǎn)單,就在路由的配置中添加上下面的代碼就可以了,你看:

{
            path:'/profile',
            component:Profile,
            meta:{
                title:'檔案'
            }
        }

??小編在配置“檔案”頁(yè)面的路由中添加了meta,當(dāng)用戶點(diǎn)擊 “檔案”跳轉(zhuǎn)到檔案頁(yè)面時(shí),該頁(yè)面的標(biāo)題就會(huì)變成“檔案”。于是乎,小編一口氣在“首頁(yè)”、“關(guān)于”、“用戶”頁(yè)面的路由配置中都添加了meta屬性,接下來(lái)讓我們一起看看效果吧~

導(dǎo)航守衛(wèi).gif

??好啦,我知道出現(xiàn)bug了 o(╥﹏╥)o 因?yàn)槭醉?yè)的標(biāo)題顯示的是“undefined”o(╥﹏╥)o 這到底為啥呢......嗚嗚嗚┭┮﹏┭┮
??后來(lái)小編知道了,因?yàn)樵谑醉?yè)中有路由的嵌套。嵌套是啥?忘記了(⊙_⊙)?就是URL后面還有該頁(yè)面想?yún)?shù),看下圖:
嵌套的路由.png

沒(méi)有嵌套的路由.png

于是乎小編打印了一下 to 是個(gè)啥玩意兒,不打不知道,一打下一跳:
image.png

??發(fā)現(xiàn) meta 并沒(méi)有任何東西,但是在matched 中的 meta 卻有,說(shuō)明我們獲取title的時(shí)候不應(yīng)該用 to.title 而應(yīng)該用 to.matched[0].mate.title 。所以結(jié)合上面兩步給出的完整代碼應(yīng)該是這樣子的:

const router = new VueRouter({
    routes:[
        {
            path:"",
            redirect:'/home'
        },
        {
            path:'/home',
            component:Home,
//使用 meta 確定路由跳轉(zhuǎn)時(shí)要修改的值
            meta:{
                title:'首頁(yè)'
            },
            children:[
                {
                    path:"",
                    redirect:"new"
                },
                {
                    path:"new",
                    component:HomeNews,
                },
                {
                    path:"message",
                    component:HomeMessage,
                }
            ]
        },
        {
            path:'/about',
            component:About,
            meta:{
                title:'關(guān)于'
            }
        },
        {
            path:'/user/:userID',
            component:User,
            meta:{
                title:'用戶'
            }
        },
        {
            path:'/profile',
            component:Profile,
            meta:{
                title:'檔案'
            }
        }
        
    ],
})
//使用 beforeEach 函數(shù)確定轉(zhuǎn)換
router.beforeEach((to,from,next) =>{
    document.title=to.matched[0].meta.title
    console.log(to)
    next()
})
終結(jié)版導(dǎo)航守衛(wèi).gif

(^-^)V成功啦!好啦,今天負(fù)責(zé)任的小編要下線啦~
?記得給小編就點(diǎn)贊ho哈哈哈?


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容