vue2.0一塊兒在懵逼的海洋裏越陷越深(六)

前言

本文章系列:vue2.0一塊兒在懵逼的海洋裏越陷越深 (http://leenty.com/tags/vuejs/)
演示場地vue2.0 Demo,這是源碼地址,以爲靠譜的話歡迎加星跟隨,有問題歡迎評論和指正?vue

在vue開發SPA應用的過程當中,多數狀況下咱們須要解決一個問題
就是在路由跳轉的過程當中須要更新你SPA應用的title
這一節不說其餘,就展現如何使用vue-router導航鉤子去解決這麼一個問題。
接下來就愉快的去玩耍啦!
去吧孩子git

正文

好的,介紹下背景,我有這麼一個博客的demo,裏面有多個版塊,每一個版塊有着不一樣的名稱(title)
先看一下Demo的路由結構github

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

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

思路

這裏思路是使用vue-router的路由全局導航鉤子去解決這個問題
在路由對象裏添加一個title字段以供路由全局導航鉤子讀取並更新頁面titlevuex

配置路由

因此第一步,先在路由對象裏添加這一個字段。
打開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這樣?「
老師:「滾出去!」ui

實際上是這樣的,後綴若是一個個加也是能夠的,但爲何不用語句幫咱們加上去呢?
這樣就一勞永逸啦,不再用本身一個個打後綴了,哈哈哈,真TM機智!
mdzzthis

路由導航鉤子介紹

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

導航是發生在路由改變時的事件,這也是爲什麼網頁的導航條叫導航條的緣由
尤大大的原話是:「正如其名,vue-router 提供的導航鉤子主要用來攔截導航,讓它完成跳轉或取消。有多種方式能夠在路由導航發生時執行鉤子:全局的, 單個路由獨享的, 或者組件級的」
說的很明白,言簡意賅,其實就是能讓你控制導航的一個方法而已
導航鉤子分爲全局,單個路由獨享和組件級別的。
但不論如何,導航鉤子都接受一個函數爲參數,並會在導航過程當中調用這個函數。
函數會被傳入3個參數,分別爲to, from, next
沒錯,你看字面意思應該理解了個大概,即:
from:你從哪裏來?(問詢消息的小弟A)
to:要到哪裏去?(問詢消息的小弟B)
next:讓不讓過去還得看老子個人!(大哥你懂不)

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

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

好的,先看看全局的寫法
全局導航鉤子 一共兩個,router.beforeEachrouter.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經過路由
})

單個路由獨享的鉤子 ,一樣是兩個方法beforeEnterafterEnter,一樣的套路。
套路以下:

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: '/' })停止導航,並跳到首頁
      }
    }
  ]
})

組件內的鉤子,依然是一對基友方法beforeRouteEnterbeforeRouteLeave
套路仍是同樣的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有沒有在變化了。
能夠看個人Demohttp://vue2.leenty.com,四處切換路由,看看標題如何變化吧!

其餘

演示地址(http://vue2.leenty.com)
源碼地址(https://github.com/leenty/vue2)
github主頁,以爲靠譜的話歡迎加星跟隨

相關文章
相關標籤/搜索