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)的作用是取消导航,这时,一切操作都停留在原页面,看起来就像什么也没发生一样。
### 回答1: Vue RouterVue.js 官方的路由管理器,用于实现单页应用 (SPA) 的路由功能。如果在使用 Vue Router 过程中出现路由跳转不起作用的情况,可能是以下几个原因导致的。 1. 路由配置错误:首先要检查路由配置是否正确。在 vue-router 的配置文件中,定义了路由的路径(path)和对应的组件(component),确保路径和组件名称正确匹配。 2. 路由链接错误:在模板中使用 router-link 指令生成链接时,确保链接的 to 属性与路由配置中的路径匹配。如果 to 属性是一个变量,也要确保该变量的值与路由配置相匹配。 3. 缺少路由出口:在初始化 Vue 实例时,需要在模板中配置一个 router-view 标签用于显示匹配到的组件。如果没有在模板中添加此标签,跳转时组件将无法显示。 4. 路由模式设置错误:Vue Router 支持多种路由模式,包括 hash 模式和 history 模式。如果未正确设置路由模式,可能导致路由无法正常跳转。在创建 Vue Router 实例时,可以使用 mode 选项指定路由模式。 5. 路由守卫阻止跳转Vue Router 提供了路由守卫功能,可以在路由跳转进行一些操作,如判断用户是否登录等。如果在路由守卫中返回 false 或调用 next(false) 阻止路由跳转,就会导致路由不起作用。检查路由守卫的逻辑是否正确。 6. 其他原因:如果以上情况都没有生,可能是其他代码逻辑或结构问题导致的。可以仔细检查代码,或者提供更多具体的错误信息,以便进一步分析和解决问题。 总之,当遇到 Vue Router 路由跳转不起作用的问题时,一定要认真排查问题的可能原因,逐个排除错误,以找到正确的解决方法。 ### 回答2: 当Vue Router路由跳转不起作用时,可以考虑以下一些可能的原因和解决方案: 1. 确保Vue Router已正确安装和配置。首先,需要在项目中安装Vue Router,并将其作为Vue实例的插件来使用。在Vue实例中应该有一个路由器对象,其中包含路由规则和要跳转的路径。 2. 检查路由路径是否正确。确保要跳转的路径在路由规则中存在,并且路径与实际跳转时使用的路径相匹配。可以使用路由对象的`push`或`replace`方法进行路由跳转,这些方法可以接收一个路径参数。 3. 确保路由器视图被正确渲染。在Vue组件中,应该有一个包含`<router-view>`标记的容器,这是用于显示路由组件的地方。如果路由没有正确显示,可能是因为没有正确放置`<router-view>`标记。 4. 检查路由的钩子函数是否正确使用。Vue Router提供了几个钩子函数,例如`beforeEach`和`beforeResolve`,可以用于在路由跳转之前进行某些操作,如验证用户身份等。如果这些钩子函数中的逻辑有问题,可能会导致路由跳转不起作用。 5. 检查浏览器的控制台输出。当路由错误时,通常会在浏览器的控制台中显示相关错误信息。通过查看控制台输出,可以更好地了解问题的具体原因。 总结:当Vue Router路由跳转不起作用时,可以先检查Vue Router的安装和配置是否正确,然后检查路径是否正确,确保正确渲染路由视图,检查路由的钩子函数和浏览器控制台输出,以找出问题所在并解决。 ### 回答3: 当vue-router路由跳转不起作用时,可能有以下几个原因: 1. 路由路径配置错误:检查路由配置文件中的路径是否正确。确保路径前面没有多余的斜杠或其他字符,并且完全匹配路由路径。 2. 没有使用router-link组件:如果没有使用对应的router-link组件,直接在代码中使用`router.push()`或`this.$router.push()`方法进行跳转是无效的。 3. 路由实例未创建:在使用路由跳转之前,需要确保已经创建了Vue Router实例,并将其注入到Vue实例中。示例代码如下: ```js import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const router = new VueRouter({ routes: [ // 路由配置 ] }) new Vue({ router, // 其他Vue实例配置 }).$mount('#app') ``` 4. 路由跳转方式错误:在使用`router.push()`方法进行跳转时,需要传入一个对象参数,示例代码如下: ```js this.$router.push({ path: '/example' }) ``` 如果需要在路由跳转中传递参数,可以使用`query`或者`params`选项,如: ```js // 使用query传递参数 this.$router.push({ path: '/example', query: { id: 1 } }) // 使用params传递参数 this.$router.push({ path: '/example', params: { id: 1 } }) ``` 5. 浏览器不支持HTML5 History模式:如果使用了HTML5 History模式进行路由跳转,在一些不支持HTML5 History API的浏览器中会导致路由跳转失败。可以尝试切换为Hash模式,或者使用polyfill来解决兼容性问题。 这些是常见的导致vue-router路由跳转失败的原因,通过检查以上几个方面可以尝试解决问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值