Vue-Router路由使用详解(二)

文章目录

      • 1.路由守卫
      • 2.路由元信息
      • 3.过渡动效
      • 4.数据获取
      • 5.滚动行为
      • 6.路由懒加载
      • 7.导航故障

1.路由守卫

  1. 全局前置守卫

    全局前置守卫的应用场景之一就是在触发路由跳转后,对其拦截判断是否登陆或登陆是否失效,根据判断结果进行处理。

    router.beforeEach((to, from, next) => {
      // 进行逻辑判断,demo
      const isLogin = localStorage.getItem("isLogin");
      // 这里的meta就是下边要说的“路由元信息”
      if (to.meta.requireLogin) {
        if (isLogin) {
          next();
        } else {
          next("/login");
        }
      } else {
        next();
      }
      if (to.name === "login") {
        if (isLogin) {
          router.push({ name: "home" });
        } else {
          next();
        }
      }
    });
    
  2. 全局解析守卫

    全局解析守卫在前置守卫后调用:

    router.beforeResolve((to, from, next) => {
      console.log("全局解析守卫", 222);
      console.log(to);
      console.log(from);
      next();
    });
    

    需要注意的是,在前置守卫中必须***通过next()放行***之后才能进入组件,才能触发下一阶段钩子。

  3. 全局后置守卫

    后置守卫原理和前置守卫相同,即,在每次路由跳转之后调用。在此钩子中可以设置相应的页面操作,比如页面title、滚动条位置、懒加载结束等操作。不同点是不会改变导航本身,没有next函数。

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

    需要注意的是,后置守卫同样需要在***解析守卫中通过next()放行***后,才能触发后置守卫。

  4. 路由内守卫

    路由内守卫原理同全局前置守卫,却别就是当前***路由内独享***,其他路由不可调用。

    {
        path: "/getUserList",
        name: "UserList",
        component: () => import("@/views/user/userTable.vue"),
        meta: {
          requireLogin: false
        },
        beforeEnter: (to, from, next) => {
          console.log("路由内守卫,路由独享");
          console.log(to);
          console.log(from);
          next(); // 必须放行
        }
    },
    
  5. 组件内守卫

    1. beforeRouteEnter

      进入组件之前调用,此时没有实例化无法直接调用this。

       beforeRouteEnter(to: RouteConfig, from: RouteConfig, next: Function): void {
          console.log("组件内守卫,进入路由前");
          console.log(this); // 进入组件之前未被实例化,无法访问this
          next((vm: object) => {
            // 异步打印出vm实例
            console.log(vm);
          });
        }
      
    2. beforeRouteLeave

      beforeRouteLeave(to: RouteConfig, from: RouteConfig, next: Function): void {
        	// 离开组件前进行确认是否离开
          // this 已经可用了,所以不支持传递回调,因为没有必要了
          console.log("组件内守卫,离开路由");
          console.log(this); // 可以直接使用this
          next();
      }
      

      注意:用了守卫钩子,需要next()放行的地方一定要放行,否则路由无法跳转。通常用来禁止用户在还未保存修改前突然离开。

    3. beforeRouteUpdate

        beforeRouteUpdate(to: RouteConfig, from: RouteConfig, next: Function): void {
          // 在当前路由改变,但是该组件被复用时调用
          // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
          // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
          // 可以访问组件实例 `this`
          // this 已经可用了,所以不支持传递回调,因为没有必要了
        }
      
  6. 完整导航解析流程

    官方总结的守卫调用顺序。

    完整调用流程

    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 的回调函数,创建好的组件实例会作为回调函数的参数传入。
  7. 守卫调用顺序

    自己通过demo总结

    被官方完整解析流程包含

    1. 全局前置守卫:对应完整流程3
    2. 路由内守卫:对应完整流程5
    3. 组件内:进入路由前:对应完整流程7
    4. 组件内:离开路由:对应完整流程2
    5. 全局解析守卫:对应完整流程8
    6. 全局后置守卫:对应完整流程10

2.路由元信息

配置路由的时候添加一个自定义对象meta,即路由元信息:

	{
    path: "/getUserList",
    name: "UserList",
    component: () => import("@/views/user/userTable.vue"),
    meta: {
      requireLogin: false,
      title: "获取用户列表"
    }
  },

meta还可以放其它信息,比如可以存储该路由相关信息(例如:设置每个路由的title,取路由的title设置为选项卡的标题)

如何在守卫中获取元信息:

router.beforeEach((to, from, next) => {
  // to.meta.requireLogin
  // to.meta.title
});

3.过渡动效

为组件添加动画效果(内容过多,之后补充)

<transition>
  <router-view></router-view>
</transition>

4.数据获取

  1. 导航完成后获取

    完成导航后,在组件生命周期内获取数据(created钩子),此时为了页面友好,需要在获取数据期间显示loading动画进行等待提示。

    created () {
        // 组件创建完后获取数据,
        // 此时 data 已经被 observed 了
        this.fetchData()
    }
    
  2. 导航完成前获取

    在为后面的视图获取数据时,用户会停留在当前的界面,因此建议在数据获取期间,显示一些进度条或者别的指示。如果数据获取失败,同样有必要展示一些全局的错误提醒。

    beforeRouteEnter (to, from, next) {
        getPost(to.params.id, (err, post) => {
          next(vm => vm.setData(err, post))
        })
    }
    

5.滚动行为

6.路由懒加载

异步加载组件

const checkbox = () => import("@/views/CheckBoxIndex.vue");
const routes: Array<RouteConfig> = [
  {
    path: "/checkbox",
    name: "Checkbox",
    component: checkbox
  }
];

7.导航故障

你可能感兴趣的:(Vue,Typescript,vue)