• Vue Router路由守卫妙用:异步获取数据成功后再进行路由跳转并传递数据,失败则不进行跳转


    问题引入

    试想这样一个业务场景:

    在用户输入数据,点击提交按钮后,这时发起了ajax请求,如果请求成功,
    则跳转到详情页面并展示详情数据,失败则不跳转到详情页面,只是在当前页面给出错误消息。
    

    难点所在

    需要注意的是,这里并没有单独的接口用于判断用户是否通过校验,而是若用户通过校验,接口就直接返回了用户需要的详情信息,未通过校验则不会返回详情信息并报错。

    常见方案问题分析

    (一)用户点击按钮后直接跳转到详情页面,在详情页面的created钩子函数中发起ajax请求获取数据
    问题在于:

    若用户未通过校验,也会先跳转到详情页面,然后再报错,
    而我们的目标是先判断是否成功,成功了再进行路由跳转。
    

    (二)将详情页面写在弹窗中,不进行路由跳转。在当前页面发起请求,成功则在弹窗中展示详情数据,失败了则不展示弹窗
    问题在于:

    弹窗中的内容特别多的情况下,排版不容易,很容易难看,毕竟弹窗一般适用于展示少量数据 ,
    并且产品的设计要求可能就是需要单独页面展示,不允许使用弹窗。
    另外,如果路由和页面都已经写好了,再去写弹窗也会额外增加不少工作量
    

    (三)发两次请求:当前页面发起第一次请求,失败了不进行跳转;成功了在详情页面再发起一次请求,获取详情数据

    这种方式肯定可行,但是问题在于:

    同一个api发送了两次请求,多发一次请求白白耗费了网络资源
    

    (四)当前页面发起请求,失败了进行错误提示;成功了,则跳转到详情页面,并通过Vuex或者空组件实现非父子组件通信的方式将数据携带至详情页面展示
    这种方式的问题在于:

    Vuex的设计目标是存储系统各组件共用的状态,例如用户登录状态、菜单伸缩收起状态,
    这里仅有两个组件,采用Vuex有种大炮打蚊子的感觉,使用空组件事件传值实现非父子组件通信
    会略显繁琐。并且这两种方式加大了系统复杂度,也容易有新坑。
    

    (五)浏览器缓存
    不用说,更加繁琐了,也偏离更远了。

    推荐解决方案:使用Vue Router的beforeRouteEnter路由导航守卫

    (一)beforeRouteEnter简介:

    它本质上,类似于Vue.js的生命周期钩子函数。它在新路由被确认前被调用,可以在里面进行数据处理,发起ajax获取数据,甚至是取消导航。当调用该守卫时,页面仍停留在原页面。该守卫执行完毕后(包括异步获取数据),才会跳转到新页面。

    (二)使用案例

    在详情组件中使用beforeRouterEnter路由守卫:

    import $axios from '@/libs/axios';
    import api from '@/api';  
    
    export default {
      name:'testComponent',
      data(){
      	return {};
      },
      beforeRouteEnter(to, from, next) {
        $axios
          .get(api.GetQueueSettingDetail, {
            params: {
              waybillKey: to.params.pickCode,
              warehouseType: 11
            }
          })
          .then(resp => {
            if (resp.success) {
              next(vm => {
                vm.carInfo = resp.result;
              });
            } else {
              next(false);
            }
          })
          .catch(() => {
            next(false);
          });
      },
    }
    

    在以上案例中,在新路由被确认前,先发起ajax请求,若成功,就将数据赋值给该组件的carInfo,并跳转到新路由。若失败,调用next(false)回调函数取消导航,页面仍停留在原页面。
    该方案相对来说,比较圆满的实现了开篇所提的业务需求,并且没有额外的开销。

    (三)参数说明

    三个参数

    • to 即将要进入的目标 路由对象
    • from 当前导航正要离开的路由
    • next 回调函数,一定要调用该方法来 resolve 这个钩子,可以在里面取消导航(next(false))或进行数据处理

    (四) 注意事项

    • beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。因而上面示例中api和axios都采用了手动导入,没有使用this.axios或者this.api的方式。
    • 访问组件实例的方式是,通过传一个回调给 next来访问组件实例,也不能使用this。在上面示例中,获取数据成功后,使用的是vm.carInfo而不是this.carInfo。
    • next(false)的作用是取消导航,这时,一切操作都停留在原页面,看起来就像什么也没发生一样。
  • 相关阅读:
    selenium批量执行脚本操作
    Monkey压力测试操作步骤说明
    loadrunner整体压测执行操作步骤
    selenium3+python3.6爬页面源码的代码
    unittest_API自动化脚本应用
    Python3.7版本unittest框架添加用例的方法
    python3中报错:TypeError: 'range' object doesn't support item deletion
    构建Hadoop集群在线datanode不在线
    Nomodulenamed pip._internal怎么解决
    模拟登陆京东并访问我的订单
  • 原文地址:https://www.cnblogs.com/twodog/p/12134730.html
Copyright © 2020-2023  润新知