处理js history.go(-1) 页面跳转 反复死循环问题

这里说一个常见的问题   js的痛点

就是 我们的 -1 返回 

列举 下列场景

登录注册2个页面  登录能跳转注册   注册可以跳转登录  且  2个页面的头部均有返回图标

A.如果返回 都使用-1  那么 当你登录注册来回点击10次的时候  其实 是 10次跳转   而 10次过后 当你开始点击返回的时候

注册可能发挥登录  登录点击返回  又回注册了 回来回往复你之前的10次跳转 但实际可能用户在登录页的返回 是想 回首页(这里不要说 登录的返回 写死返回首页,此例子 只做 处理-1 及页面死循环举例而已)如果产品允许那另当别论 如果希望做到完美 那就需要思考了

B.如果登录使用固定路径 注册使用-1  即 一个返回是跳转 一个返回是-1   则会出现死循环状态   2个页面无限切换

C.如果都是固定跳转 那么当页面有多入口进入  又有多入口离开呢  你的固定跳转是否不行  如果你说加判断 那你如何写判断 如果你说可否在路径上添加参数 作为returnurl 那么如果页面跳转层级是4层 5层呢

总之 这是一个很复杂的问题  下面直接上楼主的代码

第一部分   纯js代码 不涉及 vue react

/**
 * Created by qianggao on 2018/8/15.
 */

jQuery.extend( {
    _initBackUrl:function (key,options,flag) {
        if(!!flag){
            if(Array.isArray(options)){ // 如果为数组 并且长度大于0 说明有不想去的地方
                var prevUrl=document.referrer; // 获得上一级路径
                if(prevUrl!= ""){
                    for ( var i = 0; i <options.length; i++){
                        if(prevUrl.indexOf(options[i]) > -1){ // 如果一旦大于-1 说明有 则保存
                            window.sessionStorage.setItem(key,prevUrl);
                        }
                    }
                }

            }else{
                alert("参数路径格式不对哦,字符串数组哦");
            }
        }else{
            if(Array.isArray(options) && options.length>0 ){ // 如果为数组 并且长度大于0 说明有不想去的地方
                var noBackUrlS=options.concat([window.location.pathname]); // 不保存的数组    没弄完呢  得数组切割
                var urlIsSaveFlag=true; // 默认来了就保存的标志
                var prevUrl=document.referrer; // 获得上一级路径
                if(prevUrl!=""){
                    for ( var i = 0; i <noBackUrlS.length; i++){
                        if(prevUrl.indexOf(noBackUrlS[i]) > -1){ // 如果一旦大于-1 说明有 则不保存 这种判断(高概率)效率高于==-1
                            urlIsSaveFlag=false;
                            break;
                        }
                    }
                }else{
                    urlIsSaveFlag=false;
                }
                if(urlIsSaveFlag){ // 保存路径
                    window.sessionStorage.setItem(key,prevUrl);
                }
            }else{
                alert("参数路径格式不对哦,字符串数组哦");
            }
        }
    },
    _goBack:function (key) {
        if(key != null){
            var returnUrl= window.sessionStorage.getItem(key);
            // window.sessionStorage.removeItem(key);
            if(returnUrl != null){
                window.location.href=returnUrl;
            }else{
                history.go(-1)
            }
        }else{
            history.go(-1)
        }

    }
})

使用方式

// 如果入口太多  而  出口很少  那就适合noUrls 即 不需要保存的路径  然后 最后设置false
var noUrls=["/a/b","/Qa/qa"];  

$._initBackUrl("qaCommentReturnUrl",noUrls,false);

function goBack() {
  $._goBack("qaCommentReturnUrl");
}

// 如果入口太少  而  出口很多  那就适合yesUrls 即 需要保存的路径  然后 最后设置true
var yesUrls=["/a/b","/Qa/qa"];  

$._initBackUrl("qaCommentReturnUrl",yesUrls,true);

function goBack() {
  $._goBack("qaCommentReturnUrl");
}

第二部分 vue 如何做这种操作

// 第一种情况 如果是入口少  出口多  则选用 saveurls
// 首先  
beforeRouteEnter (to, from, next){
  next(vm => {
    // 通过 `vm` 访问组件实例,将值传入oldUrl  
    // 这里本不该有nosaveurl  之所以添加nosaveurl 是因为saveurl里存在一级路由 做数组判定的时候 二级路由和可能是包含一级路由 所以添加nosaveurls  重点就是nosaveurls后面的 '/' 
    // 举例 一级路由/index  二级路由 /index/haha 如果想单独判断/index 而不是误判 /index/haha 则这2个路由的区别就是 一级路由 没有第二个 斜杠 ‘/’ 所以 这是重点  
    const saveUrlS=['/index','/mailBuy/mailBuyDetail','/mailBuy']
    const noSaveUrlS=['/index/','/mailBuy/']

    if(saveUrlS.indexOf(from.path) > -1 && noSaveUrlS.indexOf(from.path) == -1){
       vm.oldUrl = from.path
       vm.oldQuery = from.query
    }
  })
}

// 然后
this.$nextTick(()=>{
  // 验证是否获取到了上页的url
  if(this.oldQuery != undefined){
     this.$setStore('mailBuyNewPurchaseBackUrl',JSON.stringify({path:this.oldUrl,query:this.oldQuery}))
  }else if(this.oldUrl!= undefined){
     this.$setStore('mailBuyNewPurchaseBackUrl',JSON.stringify({path:this.oldUrl}))
  }
  this.goUrl= JSON.parse(this.$getStore('mailBuyNewPurchaseBackUrl')) || -1
})

// 第二种情况 如果是入口多  出口少  则选用 nosaveurls
// 首先
beforeRouteEnter (to, from, next){
  next(vm => {
    // 通过 `vm` 访问组件实例,将值传入oldUrl
    const noSaveUrlS=['/mailDetail/matchBidList']
    if(noSaveUrlS.indexOf(from.path) == -1){
      vm.oldUrl = from.path
      vm.oldQuery = from.query
    }
  })
}

// 然后
mounted(){
  this.$nextTick(()=>{
    // 验证是否获取到了上页的url
    if(this.oldQuery != undefined){
       this.$setStore('mailDetailsBackUrl',JSON.stringify({path:this.oldUrl,query:this.oldQuery}))
    }else if(this.oldUrl!= undefined){
       this.$setStore('mailDetailsBackUrl',JSON.stringify({path:this.oldUrl}))
    }
    this.goUrl= JSON.parse(this.$getStore('mailDetailsBackUrl')) || -1  
  })
}

我的主要思路就是 利用数组存储要保存的返回路径 或者不保存的返回路径

然后利用sessionstorage去进行存储和读取 这些都写在了vue的2个生命

周期函数内

希望可以帮到你们~

发布了100 篇原创文章 · 获赞 75 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/gaoqiang1112/article/details/82013044