1. 修改標題需求
1.1 需求
需求: 在SPA應(yīng)用中,如何改變網(wǎng)頁的標題
分析:
- 網(wǎng)頁的標題是通過
title標簽來顯示的, - 但是在SPA應(yīng)用中只有一個固定HTML,因此切換組件,標題不會改變
- 可以通過JavaScript 來修改
title標簽的內(nèi)容, 通過window.document.title修改
1.2 解決方案
思路:
- 先前講過生命周期,在進行路由跳轉(zhuǎn)時,會進行組件顯示的切換
- 每一個組件都會經(jīng)歷組件自己的生命周期
- 離開的組件組件會被銷毀,
- 進入當前路由的組件,會經(jīng)歷組件的創(chuàng)建與掛在
- 因此我們可以了利用生命周期的鉤子函數(shù)配合
document修改title值
示例代碼:
Home組件
<script>
export default {
name:"Home",
created(){
document.title = "首頁"
}
}
</script>
解決方法分析:
- 這樣就需要我們在每一個頁面組件都需要手動修改
title內(nèi)容 - 如果頁面組件過多,在開發(fā)和后期維護上都是一個麻煩
思考:
- 就像咱們
axios攔截功能一樣,我們也需要一個攔截 - 這個攔截可以知道我們路由跳轉(zhuǎn)是從哪個組件跳轉(zhuǎn)到哪一個組件
- 這樣我們就可以通過你將要去哪個路由,讓
title顯示哪個路由中對于的標題信息
這就是我們將要學習的全局導(dǎo)航守衛(wèi).
2. 全局導(dǎo)航守衛(wèi)
2.1 什么是導(dǎo)航守衛(wèi)
導(dǎo)航守衛(wèi)說的通俗一點,就在在路由跳轉(zhuǎn)在中間添加的一層攔截,
說明:
-
vue-router提供的導(dǎo)航的導(dǎo)航守衛(wèi)主要用來監(jiān)聽路由的進入和離開 -
vue-router提供了beforeEach和afterEach鉤子函數(shù),會在路由跳轉(zhuǎn)前和跳轉(zhuǎn)后觸發(fā)
2.2 導(dǎo)航守衛(wèi)的鉤子函數(shù)
vue-router提供了兩個全局導(dǎo)航守衛(wèi)
-
beforeEach全局守衛(wèi), 也叫作前置守衛(wèi) -
afterEach全局守衛(wèi), 也叫后置守衛(wèi),
導(dǎo)航守衛(wèi)鉤子函數(shù)的參數(shù)是一個回調(diào)函數(shù),
2.2.1 beforeEach全局守衛(wèi)
beforeEach全局守衛(wèi)的回調(diào)函數(shù)接受三個參數(shù),為to,from,next
三個參數(shù)說明:
-
to跳轉(zhuǎn)進入的目標路由對象 -
form當前準備離開的路由對象 -
next調(diào)用該方法后,進入下一個鉤子, 作用類似于express或者koa中中間件里調(diào)用的next
next函數(shù)使用說明
- 如果
next函數(shù)正常調(diào)用next()表示正常進入跳轉(zhuǎn)路由,導(dǎo)航狀態(tài)為確認 - 如果
next函數(shù)在調(diào)用是傳入false,如next(false), 表示終端導(dǎo)航跳轉(zhuǎn) -
next函數(shù)還可以傳參,表示跳轉(zhuǎn)到指令路由next("/"),或next({path:"/"})參數(shù)的路由,
等著咱們看示例使用
2.2.2 afterEach`全局守衛(wèi)
afterEach全局守衛(wèi)的回調(diào)函數(shù)接受二個參數(shù),為to,from
兩個個參數(shù)說明:
-
to跳轉(zhuǎn)進入的目標路由對象 -
form當前準備離開的路由對象
為什么afterEach沒有next參數(shù)呢,因為在afterEach被調(diào)用時, 路由已經(jīng)跳轉(zhuǎn)完畢,
2.3 使用全局守衛(wèi)修改標題
2.3.1 使用全局守衛(wèi)說明
使用全局守衛(wèi)修改標題說明:
- 因為全局導(dǎo)航守衛(wèi)回調(diào)函數(shù)參數(shù)
to,form表示的是路由對象, - 因此如過想在路由對象中獲取
title值,就必須現(xiàn)在路由映射中定義title值 - 將
title定義在meta元數(shù)據(jù)對象中, 元數(shù)據(jù)修飾數(shù)據(jù)的數(shù)據(jù) - 在跳轉(zhuǎn)路由是通過跳轉(zhuǎn)路由獲取
title值,然后修改頁面標題
2.3.2 修改路由
修改路由,添加title數(shù)據(jù)
{
path:'/home',
component: Home,
meta:{title:"首頁"}, // 元數(shù)據(jù)中添加title信息
},
2.3.3 在全局守衛(wèi)中修改標題
// 使用全局導(dǎo)航守衛(wèi)
router.beforeEach((to,from,next) => {
// to 就是將要去的路由, 就是$route 對象
// from 是離開的路由, 就是之前顯示路由 也是$route 對象
// console.log(to);
// console.log(from);
document.title = to.matched[0].meta.title
next()
})
3. 路由獨享守衛(wèi)
3.1 路由獨享守衛(wèi)說明:
- 使用的鉤子函數(shù)與全局導(dǎo)航守衛(wèi)一致,為
beforeEnter - 不同的是:路由獨享守衛(wèi)是定義在路由記錄中,全局導(dǎo)航守衛(wèi)是定義在入口文件中
- 路由獨享守衛(wèi)只在當前路由進入時有效,全局導(dǎo)航守衛(wèi)是所有路由跳轉(zhuǎn)都會被攔截
3.2 例如:
現(xiàn)在只想攔截進入/離開/article路由,就可以給/article路由使用路由獨享守衛(wèi)
{
path:'/article',
component: Article,
meta:{title:"文章"},
beforeEnter(to,from,next){
// 當路由跳轉(zhuǎn)到/article是觸發(fā)路由獨享守衛(wèi)
console.log(to);
console.log(from);
console.log(next);
next()
},
},
4. 組件內(nèi)的路由守衛(wèi)
除了在全局和確定的路由中定義路由導(dǎo)航守衛(wèi),還可以在組件中定義路由導(dǎo)航守衛(wèi)
4.1 組件內(nèi)的路由守衛(wèi)說明
- 組件內(nèi)的守衛(wèi)是定義在組件內(nèi)部,組件選項對象中的路由守衛(wèi)
- 組件內(nèi)路由守衛(wèi)有三個,為:
beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave -
beforeRouteEnter組件創(chuàng)建前調(diào)用,不能使用組件實例this -
beforeRouteUpdate路由被改變,但是組件被復(fù)用時調(diào)用,比如動態(tài)路由 -
beforeRouteLeave導(dǎo)航離開該組件時調(diào)用
4.2 例如
在文章組件中使用組件內(nèi)的路由守衛(wèi)
<script>
export default {
name:"Article",
beforeRouteEnter(to,from,next){
// 不!能!獲取組件實例 `this`
// 因為當守衛(wèi)執(zhí)行前,組件實例還沒被創(chuàng)建
next()
},
beforeRouteUpdate(to,from,next){
// 在當前路由改變,但是該組件被復(fù)用時調(diào)用
// 帶有動態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時候,
// 由于會渲染同樣的 Article 組件,
// 因此組件實例會被復(fù)用。而這個鉤子就會在這個情況下被調(diào)用。
// 可以訪問組件實例 `this`
next()
},
beforeRouteLeave(to,from,next){
// 導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用
// 可以訪問組件實例 `this`
next()
}
}
</script>
4.3 關(guān)于組件內(nèi)路由守衛(wèi)的next參數(shù)
說明:
-
next是一個函數(shù), - 因為在
beforeRouteEnter路由守衛(wèi)中不能通過this訪問組件實例 - 因此在
beforeRouteEnter守衛(wèi)中next可以接受一個回調(diào)函數(shù),回調(diào)函數(shù)的形參就是組件實例 -
beforeRouteUpdate和beforeRouteLeave中能通過this獲取組件實例,固不支持回調(diào)函數(shù)