zoukankan      html  css  js  c++  java
  • vue router 需要go(-2)才能返回前一页

    背景:

    团队内遇到了好几次了,比如新建跳转到页面后,$router.go(-2)才能返回列表页面,并且query内写的参数的key也没了,所以趁着今天有时间就解决了一下,分享一下。

    先说一下问题所在,方便大家先拿去测试,如果对了,那就是俺蒙对了;如果不对,那就是俺太菜了。

    问题所在:

    router的query为undefined(目前就发现这一种),就会导致vueRouter内部报错,但是我没听说过有这种说法,所以我去跟着源码走了一圈,发现有一个pushState,try和catch走catch了,所以走了两遍router.push(没去细看router哪里有捕获这个错误的,只能看到这里执行两次push)。

    解决方法:

    假设问题代码如下:

    // this.age = undefined
    // this.name = jin
    this.$router.push({
      path: '/user',
      query: {
        name: this.name,
        age: this.age
      }
    })
    

    解决办法如下:

    1. 吧query改为path后面拼接(不建议), 如下:
    this.$router.push({
      path: `/user?name=${this.name}&age=${this.age}`
    })
    
    1. query内增加兼容处理,如下:
    this.$router.push({
      path: '/user',
      query: {
        name: this.name || '',
        age: this.age || ''
      }
    })
    

    第二种方法比较正规,并且如果和我们一样对router进行封装了的话,这样的判断处理可以放到通用的地方,就像我们好多处都有这个问题,一下就解决了。

    我排查的过程:

    这部分是我对这个问题的原理问题分析,不对的地方,希望大佬们指出。

    1. 为什么参数丢失了

    45F3B7B6D5F677973FF09BF9A2F1BEAF.jpg

    vue中处理query参数的地方,这个函数作用看名字就可以看出来是将query转换为stringify,我们可以看到当value为undefined时候直接return不进行处理

    1. hash方法源码
    HashHistory.prototype.push = function push(location, onComplete, onAbort) {
        var this$1 = this;
        var ref = this;
        var fromRoute = ref.current;
        this.transitionTo(location, function(route) {
            pushHash(route.fullPath);
            handleScroll(this$1.router, route, fromRoute, false);
            onComplete && onComplete(route);
        }, onAbort);
    };
    
    1. 这个问题的根源

    细节的原因,我懒得去跟踪了,可以确定一个大概的路。

    排查的时候,我发现如果有问题,其实都会触发两次上面的push方法,并且吧第二次吧undefined参数去掉了。

    报错的地方为,下面这段代码的try/catch, 重新对导航执行了一次assign,而route可以监听每一次location的操作,所以造成了push两次的问题(这个我也想不明白为啥会进catch但是通过浏览器可以看到确实进了catch,但是e打印也是undefined)

    function pushState(url, replace) {
        saveScrollPosition();
        // try...catch the pushState call to get around Safari
        // DOM Exception 18 where it limits to 100 pushState calls
        var history = window.history;
        try {
            if (replace) {
                // preserve existing history state as it could be overriden by the user
                var stateCopy = extend({}, history.state);
                stateCopy.key = getStateKey();
                history.replaceState(stateCopy, '', url);
            } else {
                history.pushState({
                    key: setStateKey(genStateKey())
                }, '', url);
            }
        } catch (e) {
            window.location[replace ? 'replace' : 'assign'](url);
        }
    }
    

    最后,希望能对大家有所帮助吧。如分析不对,还请大佬帮忙指出问题所在

  • 相关阅读:
    (转)sysbench部署与参数详解
    (转)MySQL自带的性能压力测试工具mysqlslap详解
    (转)mysql双机热备的实现
    (转)linux运维必会MySQL企业面试题
    (转)MySQL出现同步延迟有哪些原因?如何解决?
    (转)mysql数据库高可用高扩展性架构方案实施
    java.IO
    String类的编码和解码问题
    编码表的概述和常见编码表
    05_打字游戏
  • 原文地址:https://www.cnblogs.com/jinzhenzong/p/15211660.html
Copyright © 2011-2022 走看看