美文网首页
vue导航守卫

vue导航守卫

作者: 喜欢未来你的我 | 来源:发表于2018-01-23 17:08 被阅读0次

    导航解析流程

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

    导航守卫详解

    正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的(beforeEach,afterEach,beforeResolve), 单个路由独享的(beforeEnter), 或者组件级的(beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave)。

    测试用例

    这里主要测试路由守卫,创建了3个vue文件,1个路由规则文件为重要测试文件:

    先贴上路由文件:

    import Vue from 'vue'
    import Router from 'vue-router'
    
    Vue.use(Router)
    
    import home from '../components/home'
    import router1 from '../components/router1'
    import router2 from '../components/router2'
    
    let router = new Router({
      routes: [
        {
          path: '/',
          name: 'home',
          component:home,
          beforeEnter:(to,from,next) => {
            console.log(to);
            console.log(from);
            next();
          }
        },
        {
          path: '/router1',
          name: 'router1',
          component:router1,
          beforeEnter:(to,from,next) => {
            console.log('hello');
            next();
          }
        },
        {
          path: '/router2',
          name: 'router2',
          component:router2
        }
      ]
    });
    // 全局前置守卫
    router.beforeEach((to,from,next) => {
        console.log(to);
        console.log(from);
        if(to.name == 'router1') {
          console.log(12)
          next(false)
          return;
        }
        next();
    });
    
    // 全局后置守卫
    router.afterEach((to,from) => {
      console.log(to);
      console.log(from);
    });
    
    
    
    export default router;
    

    1.home.vue 文件

    <template lang="html">
      <div>
        <button type="button" name="button" @click="jump(1)">路由一</button>
        <button type="button" name="button" @click="jump(2)">路由二</button>
      </div>
    </template>
    
    <script>
    export default {
      name:"home",
      methods:{
        jump(num){
          this.$router.push({
            name:"router" + num
          })
        }
      }
    }
    </script>
    
    <style lang="css">
    </style>
    

    2.router1.vue

    <template lang="html">
      <div>
        <p>这是路由一</p>
      </div>
    </template>
    
    <script>
    export default {
    }
    </script>
    
    <style lang="css">
    
    </style>
    

    3.router2.vue

    <template lang="html">
      <div>
        <p>这是路由二</p>
      </div>
    </template>
    
    <script>
    export default {
    }
    </script>
    
    <style lang="css">
    </style>
    

    全局守卫

    全局守卫,就是导航触发时的前后执行相关逻辑,可为全局前置守卫(导航发生跳转之前beforeEach),全局后置守卫(导航发生跳转之后afterEach)

    // 全局前置守卫 router 为v-router实例化的对象
    router.beforeEach((to,from,next) => {  // to:去哪里去,from:从哪里来,next:
        console.log(to);
        console.log(from);
        if(to.name == 'router1') {   // 全局拦截,如果跳转到指定路由router1的话,使其不能跳转或相关逻辑
          next(false)
          return;
        }
        next();
    });
    
    router.afterEach((to,from) => {
      console.log(to);
      console.log(from);
    });
    

    路由独享的守卫

    在路由规则配置beforeEnter,当路由进入相关配置路由,会触发相关逻辑

    routes: [
        {
          path: '/',
          name: 'home',
          component:home,
          beforeEnter:(to,from,next) => {
            console.log(to);
            console.log(from);
            next();
          }
        },
        ...
    

    组件内的守卫

    就是将路由变化入口写在组件内部

    export default {
      name:"router1",
      data(){
        return {
          str:"hello"
        }
      },
      beforeRouteEnter (to,from,next) {
        console.log(to);
        console.log(from);
        console.log(this);  // undefind
        next();
      },
      beforeRouteLeave (to, from, next) {
        console.log(to);
        console.log(from);
        console.log(this);  // VueComponent
      }
    }
    

    组件内的守卫具体注意事项,我将贴上官网的代码

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

    路由元信息(meta)

    定义路由的时候可以设置meta字段,可以存储该路由相关信息(例如:设置每个路由的title,取路由的title设置为选项卡的标题)

     {
          path: '/router2',
          name: 'router2',
          component:router2,
          meta:{
            title:"router2"
          }
        }
    
    // 全局前置守卫
    router.beforeEach((to,from,next) => {
        console.log(to);
        console.log(from);
        if(to.meta.title) {
          document.title = to.meta.title;
        } else {
          document.title = '我是默认的title'
        }
        next();
    });
    

    总结

    其实vue官方文档,讲的非常清晰明朗的,自己也是理解加动手验证了这些导航守卫,总结此文来加深自己的理解

    生活寄语 :爱代码,爱生活

    相关文章

      网友评论

          本文标题:vue导航守卫

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