vue-router总结 -- 路由钩子/导航守卫

拥有回忆 提交于 2020-02-26 02:05:12


结构图

一、前言

在上一篇 vue-router总结 -- 基础使用 中,简单介绍了vue-router的安装、引用、嵌套路由、路由传参和重定向等内容,这是系列的第二篇,主要总结一下路由钩子函数的使用方法和一些常见的使用场景。

二、三大类钩子函数

路由钩子函数就是在发生路由跳转时,在每个时机调用的函数。这些函数分为三大类:

1.全局钩子函数

全局钩子函数有两个:beforeEach 和 afterEach,由路由实例调用执行。

(1) beforeEach

进入路由之前被调用,通常进行判断登录状态、鉴权等操作。

应用:登录拦截,部分地方使用伪代码形式(因为懒啊)

import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home'
import About from './components/About'

Vue.use(Router)

const router = new Router({
    routes: [
        {
            path: '/',
            name: 'Home',
            component: Home
        }, {
            path: '/about',
            name: 'About',
            component: About,
            meta: {
              auth: true // 该路由需要登录权限
            }
        }
    ]
})

router.beforeEach((to, from, next) => {
  if (to.matched.some(res => res.meta.auth)) {
    if("已登录") {
      next()
    } else {
      next({
        path: '登录页路由地址',
        query: {redirect: to.fullPath}
      })
    }
  } else {
    next()
  }
})

export default router

(2) afterEach

进入路由之后被调用,与beforeEach不同的是,这个钩子只接收两个参数,不能改变路由跳转。
应用:访问不同路由地址,显示每个页面对应的title

import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home'
import About from './components/About'

Vue.use(Router)

const router = new Router({
    routes: [
        {
            path: '/',
            name: 'Home',
            component: Home,
            meta: {title: '首页'}
        }, {
            path: '/about',
            name: 'About',
            component: About,
            meta: {
              title: '关于',
              auth: true // 该路由需要登录权限
            }
        }
    ]
})

router.afterEach((to, from) => {
  document.title = to.meta.title || ''
})

export default router

2.某个路由独享的钩子函数

只有一个:beforeEnter,在路由配置中直接定义。这个钩子用的比较少。

import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home'
import About from './components/About'

Vue.use(Router)

const router = new Router({
    routes: [
        {
            path: '/',
            name: 'Home',
            component: Home,
            meta: {title: '首页'},
            beforeEnter(to, from, next) {
              next()
            }
        }, {
            path: '/about',
            name: 'About',
            component: About,
            meta: {
              title: '关于',
              auth: true // 该路由需要登录权限
            }
        }
    ]
})

export default router

3.组件内的钩子函数

组件内的钩子函数有三个:beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave,直接被定义在每个vm实例上。

(1) beforeRouteEnter

进入组件前被调用,此时组件实例还没有被创建,所以函数内部不能访问this,如果需要访问当前vue实例,可以通过next() 方法的回调函数接收一个vm实例。
应用:访问当前vue实例的属性

export default {
    data() {
        return {
            msg: '这是消息'
        }
    },
    beforeRouteEnter(to, from, next) {
        /* 访问当前vue实例 */
        next(vm => {
            console.log(vm.msg)
        })
    }
}

(2) beforeRouteUpdate
在路由发生变化,但是组件被复用时被调用。
应用:父路由监听子路由变化
router.js

routes: [{
    path: '/',
    name: 'Home',
    component: Home,
    children: [{
        path: 'goods',
        name: 'Goods',
        component: Goods,
    }, {
        path: 'about',
        name: 'About',
        component: About,
    }]
}]

Home.vue

export default {
    beforeRouteUpdate(to, from, next) {
        console.log('子路由发生变化')
        next()
    }
}

当访问地址在 http://localhost:8080/#/goods 和 http://localhost:8080/#/about 间切换时,会触发Home.vue组件的 beforeRouteUpdate 方法。

还有一种常见应用场景是形如 /goods/:id 形式的路由,在访问 http://localhost:8080/#/goods/1 和 http://localhost:8080/#/goods/2 切换地址时,由于路由地址的变化只表示参数发生变化,页面组件并没有变化,也会执行 beforeRouteUpdate 钩子函数。

(3) beforeRouteLeave
离开组件时被调用,可以用来阻止页面离开,或者离开前销毁定时器等。
应用:页面离开前清除定时器

export default {
    beforeRouteLeave (to, from, next) {
       window.clearInterval(this.timer) //清除定时器
       next()
    }
}

三、参数说明

除了全局钩子 afterEach 接收 tofrom 两个参数以外,其他钩子都是接收了tofromnext 三个参数,各自含义:

① to:路由跳转目标路由对象。
② from:路由跳转离开路由对象。
③ next:是一个function,必须被执行,否则不会进行路由跳转,如果next(false),同样不会执行跳转。next()参数为url路径,则会发生重定向。to 和 from 都为路由对象,包含以下属性:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!