【轉】vue中的鈎子函數。。


前言

在vue開發SPA應用的過程中,多數情況下我們需要解決一個問題

就是在路由跳轉的過程中需要更新你SPA應用的 title ,

這一節不說其他,就展示如何使用 vue-router 的 導航鈎子 去解決這么一個問題。

接下來就愉快的去玩耍啦!

正文

好的,介紹下背景,我有這么一個 博客的demo ,里面有多個版塊,每個版塊有着不同的名稱( title )

先看一下Demo的路由結構

vue2.leenty.com
├── home                # 首頁版塊
├── article             # 文章版塊 │ ├── vue2-1 # 具體文章一 │ ├── vue2-2 # 具體文章二 │ ├── vue2-3 # 具體文章三 │ ├── vue2-4 # 具體文章四 │ ├── vue2-5 # 具體文章五 │ └── vue2-6 # 具體文章六 └── demo # 演示版塊 └── demo-1 # 具體演示一

好的,接下來要實現的是在切換路由的時候同時的去切換你頁面的 title

思路

這里思路是使用 vue-router 的路由全局導航鈎子去解決這個問題

在路由對象里添加一個 title 字段以供路由全局導航鈎子讀取並更新頁面 title

配置路由

所以第一步,先在路由對象里添加這一個字段。

打開 src/routes.js ( 源文件地址:https://github.com/leenty/vue2/blob/master/src/routes.js )

(注意是 routes.js ,這是咱用來存放路由對象的文件)

在原有數據的基礎上添加  title 

這里其實vue1.0和vue2.0的實現是差不多的,所以vue1.0也是可以使用的。

vue2.0路由對象提供了一個  meta 字段來給你存放一些其他信息,所以這里就可以用來存放  title 

vue1.0的話是沒有這個字段的,所以可以直接與 path 平級。

具體如下:

const routes = [
  {
    name: 'Home', path: '/', meta: { title: 'home' // 主頁的title為home }, component: require('./components/Home.vue') }, { name: 'Article', path: '/article', meta: { title: 'article' // 文章模塊相應的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

如此這般,各個頁面的 title 就預設好了

小明:”為什么 title 里不加上站點名后綴?像 demo - leenty blog 這樣?“

老師:“滾出去!”

其實是這樣的,后綴如果一個個加也是可以的,但為什么不用語句幫我們加上去呢?

這樣就一勞永逸啦,再也不用自己一個個打后綴了,哈哈哈,真TM機智!

路由導航鈎子介紹

講一講這個所謂的全局導航鈎子,聽起來玄不愣登的。。。

導航是發生在路由改變時的事件,這也是為何網頁的導航條叫導航條的原因

尤大大的原話是:“正如其名,vue-router 提供的導航鈎子主要用來攔截導航,讓它完成跳轉或取消。有多種方式可以在路由導航發生時執行鈎子:全局的, 單個路由獨享的, 或者組件級的”

說的很明白,言簡意賅,其實就是能讓你控制導航的一個方法而已

導航鈎子分為全局,單個路由獨享和組件級別的。

但不論如何,導航鈎子都接受一個函數為參數,並會在導航過程中調用這個函數。

函數會被傳入3個參數,分別為  to, from, next 

沒錯,你看字面意思應該理解了個大概,即:

from :你從哪里來?(問詢消息的小弟A)

to :要到哪里去?(問詢消息的小弟B)

next :讓不讓過去還得看老子我的!(大哥你懂不)

上面這位大哥( next )會有三種方法!

next() // 默認通過路由 next(false) // 中止導航,那么將會跳回到from的地址 next({ path: '/' }) // 跟一個路由參數對象,將會中止當前導航並跳往指向的路由

好的,先看看全局的寫法

全局導航鈎子 一共兩個,  router.beforeEach 和  router.afterEach 

一個觸發於導航開始前,一個觸發於導航開始后。用法呢,都是一樣的,如下!

const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { console.log('小弟B:哎呀媽呀!大兄弟,這是要去哪呀?', to) console.log('小弟A:大兄弟,哪兒旮沓的呀!', from) next(false) // 大哥:誰讓你過去的? // 調用next(false)中止導航,於是頁面回到跳轉前 }) router.afterEach((to, from, next) => { console.log('小弟B:哎呀媽呀!大兄弟,這是要去哪呀?', to) console.log('小弟A:大兄弟,哪兒旮沓的呀!', from) next() // 大哥:過去吧! // 調用next通過路由 })

單個路由獨享的鈎子,同樣是兩個方法 beforeEnter 和 afterEnter ,同樣的套路。

套路如下:

const router = new VueRouter({
  routes: [ { path: '/demo', component: Demo, beforeEnter: (to, from, next) => { console.log('小弟B:哎呀媽呀!大兄弟,這是要去哪呀?', to) console.log('小弟A:大兄弟,哪兒旮沓的呀!', from) next() // 大哥:過去吧! // 調用next通過路由 }, afterEnter: (to, from, next) => { console.log('小弟B:哎呀媽呀!大兄弟,這是要去哪呀?', to) console.log('小弟A:大兄弟,哪兒旮沓的呀!', from) next({ path: '/' }) // 大哥:像那邊走! // 調用next({ path: '/' })中止導航,並跳到首頁 } } ] })

組件內的鈎子,依然是一對基友方法 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() // 大哥:過去吧! // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 因為當鈎子執行前,組件實例還沒被創建 }, beforeRouteLeave (to, from, next) { console.log('小弟B:哎呀媽呀!大兄弟,這是要去哪呀?', to) console.log('小弟A:大兄弟,哪兒旮沓的呀!', from) next() // 大哥:過去吧! // 導航離開該組件的對應路由時調用 // 可以訪問組件實例 `this` } }

配合路由全局導航鈎子去更新 title

好的,三種都介紹完了,那么打開 src/router.js ,沒錯,這回是 router.js ,這是咱裝載路由的文件

在此之前,我們還需要知道在一個嵌套路由情況下的節點分布。

三個參數之一的 to 存在屬性 to.matched ,里面存在了一個包含路由節點的數組

順序是從子路由到根路由

好的,確定下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

里面的結構是這樣的

import Vue from 'vue' import VueRouter from 'vue-router' import routes from './routes' const title = 'leenty blog' // 定義我們站點的名字 Vue.use(VueRouter) /* eslint-disable no-new */ const router = new VueRouter({ mode: 'history', linkActiveClass: 'u-link--Active', routes }) // 路由導航鈎子,beforeEach,在路由進入前調用 router.beforeEach((to, from, next) => { let titleStr = '' // 檢測是不是要跳轉首頁,如果是,則不處理 if (to.name !== 'Home') { // 倒序遍歷數組獲取匹配到的路由節點,拼接各部分title for (let i = to.matched.length - 1; i >= 0; i--) { titleStr += `${to.matched[i].meta.title} - ` } } // 添加站點名 titleStr += title // 更新title document.title = titleStr // 繼續路由導航 next() }) export default router

ok,打完收工!現在可以切換路由看看 title 有沒有在變化了。

可以看我的Demo http://vue2.leenty.com ,四處切換路由,看看標題如何變化吧!

其他

原文地址:http://www.tuicool.com/articles/ERfEnm

演示地址(http://vue2.leenty.com)

源碼地址(https://github.com/leenty/vue2)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM