前言
本文章系列:vue2.0一起在懵逼的海洋里越陷越深 (http://leenty.com/tags/vuejs/)
演示場(chǎng)地vue2.0 Demo,這是源碼地址,覺得靠譜的話歡迎加星跟隨,有問題歡迎評(píng)論和指正??
aaaa
在vue開發(fā)SPA應(yīng)用的過程中绰疤,多數(shù)情況下我們需要解決一個(gè)問題
就是在路由跳轉(zhuǎn)的過程中需要更新你SPA應(yīng)用的title
损肛,
這一節(jié)不說其他帚桩,就展示如何使用vue-router
的導(dǎo)航鉤子去解決這么一個(gè)問題吹榴。
接下來就愉快的去玩耍啦!
正文
好的,介紹下背景,我有這么一個(gè)博客的demo疟游,里面有多個(gè)版塊,每個(gè)版塊有著不同的名稱(title
)
先看一下Demo的路由結(jié)構(gòu)
vue2.leenty.com
├── home # 首頁(yè)版塊
├── article # 文章版塊
│ ├── vue2-1 # 具體文章一
│ ├── vue2-2 # 具體文章二
│ ├── vue2-3 # 具體文章三
│ ├── vue2-4 # 具體文章四
│ ├── vue2-5 # 具體文章五
│ └── vue2-6 # 具體文章六
└── demo # 演示版塊
└── demo-1 # 具體演示一
好的痕支,接下來要實(shí)現(xiàn)的是在切換路由的時(shí)候同時(shí)的去切換你頁(yè)面的title
思路
這里思路是使用vue-router
的路由全局導(dǎo)航鉤子去解決這個(gè)問題
在路由對(duì)象里添加一個(gè)title
字段以供路由全局導(dǎo)航鉤子讀取并更新頁(yè)面title
配置路由
所以第一步颁虐,先在路由對(duì)象里添加這一個(gè)字段。
打開src/routes.js
(源文件地址:https://github.com/leenty/vue2/blob/master/src/routes.js)
(注意是routes.js
,這是咱用來存放路由對(duì)象的文件)
在原有數(shù)據(jù)的基礎(chǔ)上添加title
這里其實(shí)vue1.0和vue2.0的實(shí)現(xiàn)是差不多的卧须,所以vue1.0也是可以使用的另绩。
vue2.0路由對(duì)象提供了一個(gè)meta
字段來給你存放一些其他信息,所以這里就可以用來存放title
vue1.0的話是沒有這個(gè)字段的花嘶,所以可以直接與path
平級(jí)笋籽。
具體如下:
const routes = [
{
name: 'Home',
path: '/',
meta: {
title: 'home' // 主頁(yè)的title為home
},
component: require('./components/Home.vue')
},
{
name: 'Article',
path: '/article',
meta: {
title: 'article' // 文章模塊相應(yīng)的title為article
},
component: require('./components/Article.vue'),
children: [
{
name: 'vue2_1',
path: '/article/vue2_1',
meta: {
title: 'vue2.0一起在懵逼的海洋里越陷越深(一)' // 子路由也是一樣的道理
},
component: require('./md/articles/vue2-1.md')
},
// ... 子路由和父路由都差不多,所以后面的就省略了
]
},
{
name: 'Demo',
path: '/demo',
meta: {
title: 'demo' // 演示模塊title為demo
},
component: require('./components/Demo.vue'),
children: [
{
name: 'DemoVuexState',
path: 'vuex_state',
meta: {
title: 'vuex演示'
},
component: require('./components/DemoVuexState.vue')
}
]
}
]
export default routes
如此這般椭员,各個(gè)頁(yè)面的title
就預(yù)設(shè)好了
小明:”為什么title
里不加上站點(diǎn)名后綴车海?像demo - leenty blog
這樣?“
老師:“滾出去拆撼!”
其實(shí)是這樣的容劳,后綴如果一個(gè)個(gè)加也是可以的,但為什么不用語句幫我們加上去呢闸度?
這樣就一勞永逸啦,再也不用自己一個(gè)個(gè)打后綴了蚜印,哈哈哈莺禁,真TM機(jī)智!
路由導(dǎo)航鉤子介紹
講一講這個(gè)所謂的全局導(dǎo)航鉤子窄赋,聽起來玄不愣登的哟冬。楼熄。。
導(dǎo)航是發(fā)生在路由改變時(shí)的事件浩峡,這也是為何網(wǎng)頁(yè)的導(dǎo)航條叫導(dǎo)航條的原因
尤大大的原話是:“正如其名可岂,vue-router 提供的導(dǎo)航鉤子主要用來攔截導(dǎo)航,讓它完成跳轉(zhuǎn)或取消翰灾。有多種方式可以在路由導(dǎo)航發(fā)生時(shí)執(zhí)行鉤子:全局的, 單個(gè)路由獨(dú)享的, 或者組件級(jí)的”
說的很明白缕粹,言簡(jiǎn)意賅,其實(shí)就是能讓你控制導(dǎo)航的一個(gè)方法而已
導(dǎo)航鉤子分為全局纸淮,單個(gè)路由獨(dú)享和組件級(jí)別的平斩。
但不論如何,導(dǎo)航鉤子都接受一個(gè)函數(shù)為參數(shù)咽块,并會(huì)在導(dǎo)航過程中調(diào)用這個(gè)函數(shù)绘面。
函數(shù)會(huì)被傳入3個(gè)參數(shù),分別為to, from, next
沒錯(cuò)侈沪,你看字面意思應(yīng)該理解了個(gè)大概揭璃,即:
from
:你從哪里來?(問詢消息的小弟A)
to
:要到哪里去亭罪?(問詢消息的小弟B)
next
:讓不讓過去還得看老子我的瘦馍!(大哥你懂不)
上面這位大哥(next
)會(huì)有三中方法!
next() // 默認(rèn)通過路由
next(false) // 中止導(dǎo)航皆撩,那么將會(huì)跳回到from的地址
next({ path: '/' }) // 跟一個(gè)路由參數(shù)對(duì)象扣墩,將會(huì)中止當(dāng)前導(dǎo)航并跳往指向的路由
好的,先看看全局的寫法
全局導(dǎo)航鉤子一共兩個(gè)扛吞,router.beforeEach
和router.afterEach
一個(gè)觸發(fā)于導(dǎo)航開始前呻惕,一個(gè)觸發(fā)于導(dǎo)航開始后。用法呢滥比,都是一樣的亚脆,如下!
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
console.log('小弟B:哎呀媽呀盲泛!大兄弟濒持,這是要去哪呀?', to)
console.log('小弟A:大兄弟寺滚,哪兒旮沓的呀柑营!', from)
next(false) // 大哥:誰讓你過去的?
// 調(diào)用next(false)中止導(dǎo)航村视,于是頁(yè)面回到跳轉(zhuǎn)前
})
router.afterEach((to, from, next) => {
console.log('小弟B:哎呀媽呀官套!大兄弟,這是要去哪呀?', to)
console.log('小弟A:大兄弟奶赔,哪兒旮沓的呀惋嚎!', from)
next() // 大哥:過去吧!
// 調(diào)用next通過路由
})
``
**單個(gè)路由獨(dú)享的鉤子**站刑,同樣是兩個(gè)方法`beforeEnter`和`afterEnter`另伍,同樣的套路。
套路如下:
```js
const router = new VueRouter({
routes: [
{
path: '/demo',
component: Demo,
beforeEnter: (to, from, next) => {
console.log('小弟B:哎呀媽呀绞旅!大兄弟摆尝,這是要去哪呀?', to)
console.log('小弟A:大兄弟玻靡,哪兒旮沓的呀结榄!', from)
next() // 大哥:過去吧!
// 調(diào)用next通過路由
},
afterEnter: (to, from, next) => {
console.log('小弟B:哎呀媽呀囤捻!大兄弟臼朗,這是要去哪呀?', to)
console.log('小弟A:大兄弟蝎土,哪兒旮沓的呀视哑!', from)
next({ path: '/' }) // 大哥:像那邊走!
// 調(diào)用next({ path: '/' })中止導(dǎo)航誊涯,并跳到首頁(yè)
}
}
]
})
組件內(nèi)的鉤子挡毅,依然是一對(duì)基友方法beforeRouteEnter
和beforeRouteLeave
套路還是一樣的0.0
const Demo = {
template: `<div>this is a Demo </div>`,
beforeRouteEnter (to, from, next) {
console.log('小弟B:哎呀媽呀!大兄弟暴构,這是要去哪呀跪呈?', to)
console.log('小弟A:大兄弟,哪兒旮沓的呀取逾!', from)
next() // 大哥:過去吧耗绿!
// 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
// 不!能砾隅!獲取組件實(shí)例 `this`
// 因?yàn)楫?dāng)鉤子執(zhí)行前误阻,組件實(shí)例還沒被創(chuàng)建
},
beforeRouteLeave (to, from, next) {
console.log('小弟B:哎呀媽呀!大兄弟晴埂,這是要去哪呀究反?', to)
console.log('小弟A:大兄弟,哪兒旮沓的呀儒洛!', from)
next() // 大哥:過去吧精耐!
// 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
// 可以訪問組件實(shí)例 `this`
}
}
配合路由全局導(dǎo)航鉤子去更新title
好的,三種都介紹完了琅锻,那么打開src/router.js
黍氮,沒錯(cuò)唐含,這回是router.js
浅浮,這是咱裝載路由的文件
在此之前沫浆,我們還需要知道在一個(gè)嵌套路由情況下的節(jié)點(diǎn)分布。
三個(gè)參數(shù)之一的to
存在屬性to.matched
,里面存在了一個(gè)包含路由節(jié)點(diǎn)的數(shù)組
順序是從子路由到根路由
好的滚秩,確定下title文案
router | title |
---|---|
├── home |
leenty blog |
├── article |
article - leenty blog |
│ ├── vue2-1 |
vue2.0一起在懵逼的海洋里越陷越深(一) - article - leenty blog |
│ ├── ... |
... - article - leenty blog |
│ └── vue2-6 |
vue2.0一起在懵逼的海洋里越陷越深(六) - article - leenty blog |
└── demo |
demo - leenty blog |
└── demo-1 |
具體演示1 - demo - leenty blog |
里面的結(jié)構(gòu)是這樣的
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
const title = 'leenty blog'
// 定義我們站點(diǎn)的名字
Vue.use(VueRouter)
/* eslint-disable no-new */
const router = new VueRouter({
mode: 'history',
linkActiveClass: 'u-link--Active',
routes
})
// 路由導(dǎo)航鉤子专执,beforeEach,在路由進(jìn)入前調(diào)用
router.beforeEach((to, from, next) => {
let titleStr = ''
// 檢測(cè)是不是要跳轉(zhuǎn)首頁(yè)郁油,如果是本股,則不處理
if (to.name !== 'Home') {
// 倒序遍歷數(shù)組獲取匹配到的路由節(jié)點(diǎn),拼接各部分title
for (let i = to.matched.length - 1; i >= 0; i--) {
titleStr += `${to.matched[i].meta.title} - `
}
}
// 添加站點(diǎn)名
titleStr += title
// 更新title
document.title = titleStr
// 繼續(xù)路由導(dǎo)航
next()
})
export default router
ok桐腌,打完收工拄显!現(xiàn)在可以切換路由看看title
有沒有在變化了。
可以看我的Demohttp://vue2.leenty.com案站,四處切換路由躬审,看看標(biāo)題如何變化吧!
其他
演示地址(http://vue2.leenty.com)
源碼地址(https://github.com/leenty/vue2)
github主頁(yè),覺得靠譜的話歡迎加星跟隨