vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue-router导航守卫

一文详解vue-router中的导航守卫

作者:舟羽

vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航,在 vue-router 中,导航守卫是一种非常重要的功能,所以本文将详细讲解一下vue-router中的导航守卫,感兴趣的同学跟着小编一起来看看吧

导航守卫是什么

按照官方文档说明,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。

vue-router 中,导航守卫是一种非常重要的功能,它允许你在路由导航过程中添加逻辑验证和处理,比如判断用户是否登录,如果没有登录就跳转到登录页面,如果已经登录就跳转到首页。

导航守卫的分类

Vue Router 中,有三种类型的导航守卫方法可以使用:

全局守卫

全局守卫就是在路由跳转时,对整个应用内的所有路由进行拦截,然后进行一些操作。

全局守卫分为全局前置守卫全局后置守卫

全局前置守卫就是在路由跳转之前进行拦截,全局后置守卫就是在路由跳转之后进行拦截。

全局前置守卫的使用方法如下:

router.beforeEach((to, from, next) => {
  // ...
})

全局后置守卫的使用方法如下:

router.afterEach((to, from) => {
  // ...
})

路由独享守卫

路由独享守卫就是在路由跳转时,对应用内的某个特定的路由进行拦截,然后进行一些操作。

路由独享守卫的使用方法如下:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

组件内守卫

组件内守卫就是在组件内部定义的特殊守卫方法,用于处理组件级别的路由导航。常见的组件内守卫包括:

const UserDetails = {
  template: `...`,
  beforeRouteEnter(to, from) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
  },
  beforeRouteUpdate(to, from) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
  },
}

导航守卫的参数

导航守卫的参数如下:

导航守卫的执行顺序

导航守卫的执行顺序如下:

全局前置守卫 -> 路由独享守卫 -> 组件内守卫 -> 全局后置守卫

导航守卫的使用场景

全局前置守卫

router.beforeEach((to, from, next) => {
  if (to.path === '/login') {
    next()
  } else {
    const token = localStorage.getItem('token')
    if (!token) {
      next('/login')
    } else {
      next()
    }
  }
})

全局后置守卫

router.afterEach((to, from) => {
  localStorage.setItem('path', to.path)
})

路由独享守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        const token = localStorage.getItem('token')
        if (!token) {
          next('/')
        } else {
          const role = localStorage.getItem('role')
          if (to.meta.role && to.meta.role.indexOf(role) === -1) {
            next('/')
          } else {
            next()
          }
        }
      }
    }
  ]
})

组件内守卫

const Foo = {
  beforeRouteEnter(to, from, next) {
    fetchData().then(data => {
      next(vm => {
        vm.data = data; // 将数据传递给组件实例
      });
    });
  },
};
const Baz = {
  beforeRouteUpdate(to, from, next) {
    if (to.params.id !== from.params.id) {
      // 当路由参数 id 发生变化时,重新请求数据
      this.fetchData(to.params.id);
    }
    next();
  },
};
const Bar = {
  beforeRouteLeave(to, from, next) {
    if (this.hasUnsavedChanges()) {
      if (confirm('是否保存修改的数据?')) {
        this.saveData(); // 保存修改的数据
      }
    }
    next(); 
};
const Qux = {
  beforeRouteEnter(to, from, next) {
    // 在进入组件之前设置初始过渡状态
    this.transitionName = 'slide-in';
    next();
  },
  beforeRouteLeave(to, from, next) {
    // 在离开组件之前设置过渡状态
    this.transitionName = 'slide-out';
    next();
  },
};

到此这篇关于一文详解vue-router中的导航守卫的文章就介绍到这了,更多相关vue-router导航守卫内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文