也谈$router.push 不生效的故障

发布时间 2023-04-17 17:54:42作者: jack0424

1,故障现象

一个vue2的前端程序,需要根据浏览的设备类型来进入不同的path。

具体说就是PC端和手机端的home页面是分开来写的,PC端的home路径是“/home”,手机端的home路径是“/mhome”

用户点击进入程序的超链接的路径写死是进入“/home”路径(如“http://xx.yy.zz/app/home”),但是需要在进入“/home”时再次判断设备类型,如果是移动设备就跳转到“/mhome”路径。

代码如下:

home.vue

    mounted() {
        if (this.isMobile()) {
            alert('isMobile');
            this.$router.push('/mhome');
           
        } else {
            alert('not Mobile');
        }

    。。。。其它PC端代码

 

结果在手机上测试,跳出了“isMobile”信息,但是最终显示的界面并不是“/mhome”的内容,而是仍然是“/home”下的内容,也就是说以下代码执行无效:

this.$router.push('/mhome');

 

2,原因分析

按理来说,this.$router.push代码应该能将路由跳转到新页面,但是测试结果显示无效。

将代码改换成

this.$router.replace('/mhome');

结果依然无效。
后来发现,mounted()后续的代码块中,又执行了其它跳转,

 1     mounted() {
 2         if (this.isMobile()) {
 3             alert('isMobile');
 4             this.$router.push('/mhome');
 5            
 6         } else {
 7             alert('not Mobile');
 8         }
 9 
10                 。。。
11                 。。。
12         if (jumpInfo != null) {
13             let opcode=  jumpInfo.opcode;
14             if (opcode == 'score') {
15                 this.$router.replace('/xxx');
16             }
17         } else {
18             this.$router.replace('/yyy');
19         }

 

以上第15/18行执行了新的跳转,将原本准备执行的“/mhome”跳转给覆盖了。这就是跳转失效的原因所在。


3,解决方案

既然找到了原因,解决方案就简单了。在跳转后立即return,避免继续往下执行即可。

    mounted() {
        if (this.isMobile()) {
            alert('isMobile');
            this.$router.push('/mhome');
            return;
        } else {
            alert('not Mobile');
        }

 

代码如上修改后,测试通过。

 

4,总结

本问题的发生和解决显示,vue代码在执行路由操作时,不是同步阻塞型的,而是异步非阻塞型。

即调用 this.$router.push 代码后,一方面开始准备跳转,同时代码也继续向下执行,一旦二者有路由冲突,那么结果就是难以预料的了。