美文网首页Vue
Vue导航守卫

Vue导航守卫

作者: 椰果粒 | 来源:发表于2019-02-14 17:38 被阅读95次

    概念

    “导航”表示路由正在发生变化

    导航守卫表示当导航开始变化到导航变化结束的那段时间里,根据导航的变化做出一些响应。比如要跳转到一个页面时,看他是不是登录了,没登录的话,得让他先登录。

    主要是通过跳转到某处或者取消跳转来守卫导航,

    导航守卫包括全局导航守卫和局部导航守卫

    全局守卫

    vue-router全局有三个守卫

    • router.beforeEach:全局前置守卫,进入路由之前
    • router.beforeResolve:全局解析守卫,在beforeRouteEnter调用之后调用
    • router.afterEach:全局后置钩子,进入路由之后

    全局前置守卫

    一个简单的全局导航守卫的例子

    import Vue from 'vue'
    import Router from 'vue-router'
    import route from './router'
    
    Vue.use(Router)
    
    const router = new Router({
      routes: route // 路由列表
    })
    
    // 模拟用户登录与否
    const HAS_LOGIN = true;
    
    // 全局前置守卫
    // 在Router实例上进行守卫
    router.beforeEach((to, from, next) => {
      // to和from都是路由实例
      // to:即将跳转到的路由
      // from:现在的要离开的路由
      // next:函数
      // 如果未登录,就跳到登录页,如果登录了,选择哪个页面跳到哪个页面;如果登录了还去了login页面,就跳到首页。
      if (to.name !== 'login') {
        if (HAS_LOGIN) next()
        else next({ name: 'login' })
      } else {
        if (HAS_LOGIN) next({ name: 'home' })
        else next()
      }
    })
    
    // 全局解析守卫
    router.beforeResolve((to,from.next) => {
    
    })
    
    // 全局后置钩子
    router.afterEach((to,form) => {
        
    })
    
    export default router
    
    

    其中next()函数有几个取值

    • next():进行管道中的下一个钩子,如果钩子全部都执行完了,那么导航的状态就是confirmed
    • next(false):中断当前导航。如果URL改变了,实际上会重置到URL改变前的from导航那里。
    • next("/")或者next({path:"/"}):跳转到其他的地址。当前导航被中断,然后跳转到新导航。
    • next(error):如果传入的是一个error实例,则导航会被终止,且该错误会被传递给router.onError()注册过的回调。

    一定要确保调用next()方法。

    路由独享的守卫

    如果不想在全局配置路由的话,可以为某些路由单独配置守卫

    比如:给home页面单独配置守卫

      {
        path: '/',
        name: "home",
        component: Home,
        // 路由独享守卫
        beforeEnter: (to, from, next) => {
          if(from.name === 'about'){
            alert("这是从about来的")
          }else{
            alert("这不是从about来的")
          }
          next();  // 必须调用来进行下一步操作。否则是不会跳转的
        }
      }
    
    

    路由组件内的守卫

    • beforeRouteEnter():进入路由前
    • beforeRouteUpdate():路由复用同一个组件时
    • beforeRouteLeave():离开当前路由时

    在Home.vue页面中举个例子

    export default {
      // 组件内守卫
      // 因为这个钩子调用的时候,组件实例还没有被创建出来,因此获取不到this
      beforeRouteEnter (to, from, next) {
        console.log(to.name);
        // 如果想获取到实例的话
        // next(vm=>{
        //   // 这里的vm是组件的实例(this)
        // });
        next();
      },
      // 路由即将要离开的时候调用此方法
      // 比如说,用户编辑了一个东西,但是还么有保存,这时候他要离开这个页面,就要提醒他一下,还没保存,是否要离开
      beforeRouteLeave (to, from, next) {
        const leave = confirm("确定要离开吗?");
        if(leave) next()    // 离开
        else next(false)    // 不离开
      },
    }
    

    对于beforeRouteUpdate的演示例子

      beforeRouteUpdate(to,from,next){
        console.log(to.name, from.name);
        next();
      },
    
    

    beforeRouteUpdate被触发的条件是:当前路由改变,但是该组件被复用的时候。
    比如说:argu/fu1到argu/f2这个路由,都复用了arg.vue这个组件,这个时候beforeRouteUpdate就会被触发。可以获取到this实例

    一个完整的导航解析流程

    1、导航被触发。
    2、在失活的组件(即将离开的页面组件)里调用离开守卫。 beforeRouteLeave
    3、调用全局的 beforeEach 守卫。
    4、在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
    5、在路由配置里调用(路由独享的守卫) beforeEnter。
    6、解析异步路由组件
    7、在被激活的组件(即将进入的页面组件)里调用 beforeRouteEnter。
    8、调用全局的 beforeResolve 守卫 (2.5+)。
    9、导航被确认。
    10、调用全局的 afterEach 钩子。所有的钩子都触发完了。
    11、触发 DOM 更新。
    12、用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
    

    相关文章

      网友评论

        本文标题:Vue导航守卫

        本文链接:https://www.haomeiwen.com/subject/paqyeqtx.html