导航:路由正在发生变化。
导航守卫主要用来通过跳转或取消的方式守卫导航。
导航守卫被分成三种:全局的、单个路由独享的、组件内的。
说白就是当URL发生改变而触发的钩子函数,钩子函数可分为URL发生变化前,URL发生变化时,URL发生变化后

全局的导航守卫

是指路由实例上直接操作的钩子函数,触发路由就会触发这些钩子函数。
全局守卫就像是购物广场的大门的保安,进去需要出示安全码

全局前置守卫 beforeEach

触发条件:在路由跳转前触发,一般用于登录验证

  1. const router = new VueRouter({ ... })
  2. router.beforeEach((to, from, next) => {
  3. // ...
  4. })

每个守卫方法接收三个参数:

![_BUTOJ2CG9XBVHLWB3UJ7F.png
确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

示例

篡改路由的跳转
  1. router.beforeEach((to,from,next) =>{
  2. console.log('beforeEach');
  3. // 当路由要跳转到/about时将其跳转为首页 ,如果是其他路由则不做任何修改
  4. if(to.path === '/about'){
  5. next('/')
  6. }else{
  7. next()
  8. }
  9. })

效果图
导航守卫.gif

全局解析守卫 beforeResolve

和boforeEach类似,路由跳转前触发。
和beforeEach的区别:在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

  1. const router = new VueRouter({ ... })
  2. router.beforeResolve((to, from, next) => {
  3. // ...
  4. })

全局后置钩子 afterEach

和beforeEach相反,路由跳转完成后触发。
和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

  1. const router = new VueRouter({ ... })
  2. router.afterEach((to, from) => {
  3. // ...
  4. })

路由独享守卫

是指在单个路由配置的时候也可以设置的钩子函数。
就像是购物商场内每个店铺的门卫一样

beforeEnter

和beforeEach完全相同,如果都设置则在beforeEach之后紧随执行

  1. const router = new VueRouter({
  2. routes: [
  3. {
  4. path: '/home',
  5. component: Home,
  6. beforeEnter: (to, from, next) => {
  7. // ...
  8. }
  9. }
  10. ]
  11. })

组件内的守卫

是指在组件内执行的钩子函数,类似于组件内的生命周期,相当于为配置路由的组件添加的生命周期钩子函数。
就像是购物广场内店铺中都有一套一模一样的预警设置

beforeRouteEnter

路由进入之前调用。
在该守卫内访问不到组件的实例,this值为undefined。在这个钩子函数中,可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数,可以在这个守卫中请求服务端获取数据,当成功获取并能进入路由时,调用next并在回调中通过 vm访问组件实例进行赋值等操作,(next中函数的调用在mounted之后:为了确保能对组件实例的完整访问)。

  1. beforeRouteEnter (to, from, next) {
  2. // 在渲染该组件的对应路由被 confirm 前调用
  3. // 不!能!获取组件实例 `this`
  4. // 因为当守卫执行前,组件实例还没被创建
  5. next( vm => {
  6. // 通过 `vm` 访问组件实例
  7. })
  8. }

beforeRouteUpdate

在当前路由改变时,并且该组件被复用时调用,可以通过this访问实例。
何时组件会被复用?

  • 动态路由间互相跳转
  • 路由query变更
    1. beforeRouteUpdate (to, from, next) {
    2. // 在当前路由改变,但是该组件被复用时调用
    3. // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    4. // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    5. // 可以访问组件实例 `this`
    6. },

    beforeRouteLeave

    导航离开该组件的对应路由时调用,可以访问组件实例this。
    1. beforeRouteLeave (to, from, next) {
    2. // 导航离开该组件的对应路由时调用
    3. // 可以访问组件实例 `this`
    4. }

    完整的导航解析过程

    image.png