前言

在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)

【转】vue中的钩子函数。。的更多相关文章

  1. vue中的钩子函数的理解

    接下来我们对几个钩子函数进行解释 beforeCreated:这个钩子函数实在vue实例创建后,触发的.这个时候还没有进行data里的数据监听和事件的初始化 其实大家很多时候都会在created钩子函 ...

  2. vue中的钩子函数

    什么是vue的钩子函数? Vue 实例在被创建时,会经过一系列的初始化过程,初始化过程中会运行一些函数,叫做生命周期钩子函数,通过运用钩子函数,用户在可以在Vue实例初始化的不同阶段添加自己的代码,以 ...

  3. Vue -自定义指令&钩子函数

    除了核心功能默认内置的指令,Vue也允许注册自定义指令 页面加载后,让文本框自动获取焦点,原生js做法是获取文本框元素后调用focus()方法,但Vue不建议手动操作DOM元素,所以此时要自定义指令 ...

  4. Vue生命周期 钩子函数和组件传值

    Vue生命周期 钩子函数 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等. 同时在这个过程中也会运行一 ...

  5. VUE生命周期中的钩子函数及父子组件的执行顺序

    先附一张官网上的vue实例的生命周期图,每个Vue实例在被创建的时候都需要经过一系列的初始化过程,例如需要设置数据监听,编译模板,将实例挂载到DOM并在数据变化时更新DOM等.同时在这个过程中也会运行 ...

  6. vue 组件中的钩子函数 不能直接写this

    export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ next(vm=>{ vm.nu ...

  7. VueRouter和Vue生命周期(钩子函数)

    一.vue-router路由 1.介绍 vue-router是Vue的路由系统,用于定位资源的,在页面不刷新的情况下切换页面内容.类似于a标签,实际上在页面上展示出来的也是a标签,是锚点.router ...

  8. vue之router钩子函数

    模块一:全局导航钩子函数 1.vue router.beforeEach(全局前置守卫) beforeEach的钩子函数,它是一个全局的before 钩子函数, (before each)意思是在 每 ...

  9. Vue系列之 => 钩子函数生命周期

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. BGP表

    BGP是一种基于策略的路由选择协议,让AS能够根据多种BGP属性来控制数据流的传输.运行BGP的路由器交换被称为路径矢量或者属性的NLRI.路径矢量信息中包含一个BGP-AS号列表称为AS-PATH属 ...

  2. poj 3417 Network 题解

    题意: 先给出一棵树,然后再给出m条边,把这m条边连上,然后剪掉两条边,一条是原边,一条是新边,问有多少种方案能使图不连通. 思路: 从原边的角度看 1.树加边,一定成环,加一条(u,v)边就有u-& ...

  3. HDU 2629 Identity Card

    简单题 给出身份证号 判断住址 和出生年月 熟练字符串的操作 主要是string::substr(s, l)//s:起始位置 l长度 #include <iostream> #includ ...

  4. [NOIP2003] 提高组 洛谷P1040 加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  5. Arduino学习笔记0---开发板的了解

    Arduino的入门文档https://wenku.baidu.com/view/4040861d58fafab069dc02d4.html?from=search,共61页的文档,看完就差不多可以入 ...

  6. 使用Navicat进行数据库对比同步

    使用Navicat进行数据库对比同步 当有多个数据库时,有时会出现结构或者数据不同步的问题,这时候可以使用navivat工具对比同步( 我的Navicat版本是11.0.17). 参考博客: 岁伏的博 ...

  7. UVA 11806 组合数学+容斥

    UVA: https://vjudge.net/problem/UVA-11806 AC代码 #include <bits/stdc++.h> #define pb push_back # ...

  8. Windows——cmd findstr 字符串查找增强使用说明

    在文件中寻找字符串. 复制代码代码如下: FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [ ...

  9. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  10. 在CentOS上把MySQL从5.5升级到5.6

    在CentOS上把MySQL从5.5升级到5.6 摘要:本文记录了在CentOS 6.3上,把MySQL从5.5.28升级到5.6.19的过程. 1. 概述 在我做的一个项目中,最近我对生产服务器上的 ...