网站首页 » 前端开发 » Vue » Vue 导航守卫(钩子函数)
上一篇:
下一篇:

Vue 导航守卫(钩子函数)

前言

所谓的 Vue 路由导航守卫,也就是我们常说的生命周期钩子函数,导航守卫只是官方的称呼,在这里我们不妨把它叫做钩子函数,钩子函数的意思就是在特定的时刻 Vue 会自动触发这个方法,我们可以通过这些个钩子函数,实现一些功能,比如,某些页面需要登录后才可以访问、某些页面需要用户达到什么等级才可以访问,又或者是跳转页面后修改一些信息等等,我们就可以通过路由导航守卫来拦截并作相应的处理。

Vue 路由导航守卫之旅

路由导航守卫分两种,一种是全局的钩子函数,另一种就是局部的钩子函数。下面我们就一个一个来了解。

全局钩子函数

全局的钩子函数有两个,beforeEach() 和 afterEach() ,他们都挂载在 router 实例上,我们可以通过 router 实例来调用,下面是一个完整的路由配置及全局的钩子函数使用示例代码:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import Html5 from '@/components/Html5'
import Angular from '@/components/Angular'
import About from '@/components/About'

Vue.use(Router)
let router = new Router({
  linkActiveClass: 'active',
  routes: [{
      path: '/',
      name: 'Home',
      component: Home,
      meta: {
        menuName: '主页',
        index: 1
      }
    },
    {
      path: '/angular',
      name: 'Angular',
      component: Angular,
      meta: {
        menuName: 'ANGULAR',
        index: 2,
        login: true
      }
    },
    {
      path: '/html5',
      name: 'Html5',
      component: Html5,
      meta: {
        menuName: 'HTML5',
        index: 3
      }
    }, {
      path: '/about',
      name: 'About',
      component: About,
      meta: {
        menuName: '关于',
        index: 4
      }
    }
  ]
})

// 进入路由前方法勾子
router.beforeEach((to, from, next) => {
  /*
    to 目标路由
    from 源路由
    next 跳转到下一个路由
  */
  if (to.meta.login) {
    // 如果需要,则跳转到登录页
    next('/login');
  } else {
    // 如果不需要,则直接跳转到对应路由
    next();
  }
});

// 进入路由后方法勾子
router.afterEach((to, from) => {
  /*
    to 目标路由
    from 源路由
  */
  if (to.meta.menuName) {
    console.log(to.meta.menuName);
  } else {
    console.log('暂无名称');
  }
});

export default router;

beforeEach() 方法接收三个参数,afterEach() 方法接收两个参数。

关键方法

beforeEach() 方法必需要调用next() 方法,否则路由不会导航到下一个页面,除非你确实不想让转跳转。你可以住next() 方法中传入参数,布尔值(false 表示不跳转,true 表示跳转,如是字符串,则表示要将要跳转的路由)。

局部钩子函数

局部钩子函数可以写在两个地方,一个是写在组件对应的路由配置中,一个是直接写在组件中。

下面我们先来看看写在路由配置中的钩子函数,这个写法跟全局的钩子函数写法差不多,只不之函数名字不一样(beforeEnter()),参数都是一样的。

......
{
{
  path: '/angular',
  name: 'Angular',
  component: Angular,
  beforeEnter(to, from, next) {
    /*
      to 目标路由
      from 源路由
      next 跳转到下一个路由
    */
    if (to.meta.menuName) {
      console.log(to.meta.menuName);
    } else {
      console.log('暂无名称');
    }

  },
  meta: {
    menuName: 'ANGULAR',
    index: 2,
    login: true
  }
},
......

下面我们来看最后一个,组件中的钩子函数,有三个钩子函数分别是:beforeRouteEnter()、beforeRouteUpdate()、beforeRouteLeave() 。这种个函数都接收三个参数to、from 和 next 。

export default {
  name: "Parent",
  beforeRouteEnter(to, from, next) {
    console.log(this); // undefined
    next(vm => {
      // vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
      console.log(vm);
    });
  },
  beforeRouteUpdate(to, from, next) {
    console.log("beforeRouteUpdate");
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log("beforeRouteLeave");
    next();
  }
};

上面的 beforeRouteUpdate() 函数的应用场景比较特殊一点,当组件中有子导航时,我们就可以在这个父组件中使用这个方法来监控子路由的跳转了,然后在父组件中作出相应的处理。除了使用 beforeRouteUpdate() 函数外,我们还可以在父组件中使用 watch 来监听路由的变量,效果是差不多的。但是你还得根据实际情况来判断该使用哪一种方式处理。

下面给出父子组件之前的代码(包括模板代码,路由配置代码)

路由关系
{
  path: '/parent',
  name: 'Parent',
  component: Parent,
  meta: {
    menuName: '父组件',
    index: 5
  },
  children: [{
    path: '/childFirst',
    name: 'ChildFirst',
    meta: {
      menuName: '子组件一',
      index: 6
    },
  }, {
    path: '/childSecond',
    name: 'ChildSecond',
    meta: {
      menuName: '子组件二',
      index: 7
    },
  }]
}
App.vue 部分代码
<template>
  <div id="app">
      <div class="container">
          <nav class="navbar navbar-default">
              <div class="navbar-header">
                <a class="navbar-brand" href="#">云库网</a>
              </div>
              <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <router-link to="/" tag="li" exact><a>首页</a></router-link>
                    <router-link to="/parent" tag="li"><a>父组件</a></router-link>
                </ul>
              </div>
          </nav>
          <transition :name="run" mode="out-in"> 
            <router-view></router-view>
          </transition>
      </div>
  </div>
</template>
parent.vue 模板代码
<template>
 <div>
    <ul>
     <li><router-link :to="{name:'ChildFirst'}">子组件一</router-link></li>
     <li><router-link :to="{name:'ChildSecond'}">子组件二</router-link></li>
   </ul>
   <transition> 
    <router-view/>
   </transition>
</div>
</template>

估计这样就你就会更加清楚前面说的父子组件之间的关系了。上面的 :to=”{name:’ChildFirst’} 你也不要大惊小怪,作用跟直接添加 path 属性值是一样的。你可以看看这篇文章《Vue 百科全书(珍藏版)》里面有相关的介绍。

 

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/vue-navigation-guards/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END