×

浅谈下微信小程序中的路由(页面跳转、返回、刷新、页面栈)

作者:Terry2018.09.20来源:Web前端之家浏览:76987评论:0

500.jpg

什么是小程序里的“路由”?路由器吗?蒙蔽?好吧,在WEB应用中它其实就是分组数据包从源到目的地时,决定端到端路径的网络范围的进程;在小程序里就是设置页面的跳转,返回,自动刷新等一些功能。

而在微信小程序里,“路由”有很多限制,所以我们在开发小程序的时候,需要深入了解,否则就会掉坑里,被人笑话。微信小程序官方文档里提供了5种:wx.redirectTo(Object object)、wx.reLaunch(Object object)、wx.navigateTo(Object object)、wx.switchTab(Object object)、wx.navigateBack(Object object)。接下来逐个分析下。

wx.redirectTo(Object object)

关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到 tabbar 页面。

参数

Object object

属性类型默认值是否必填说明支持版本
urlstring
需要跳转的应用内非 tabBar 的页面的路径, 路径后可以带参数。参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔;如 'path?key=value&key2=value2'
successfunction
接口调用成功的回调函数
failfunction
接口调用失败的回调函数
completefunction
接口调用结束的回调函数(调用成功、失败都会执行)

说明:这里一定要注意,在使用redirectTo()的时候,不能跳转到底部导航的页面;如果一个页面用了它来跳转,返回后不可逆,因为跳转后直接被关闭,一般用在多个页面的跳转,然后从三级页面,返回到首页【跳级返回】。

不懂?来看个例子。

比如我最近做的一个答题项目需求:首页》答题》成功。这个流程其实是可以可逆的,但是我们要求,答题成功后,返回后,直接到首页,而不是答题页面,那么在答题页面跳转到成功页面就要用到redirectTo。基本的JS写法:

wx.redirectTo({        
  //目的页面地址
 url: 'pages/index/index',
 success: function(res){
 },
 ...
})

wx.reLaunch(Object object)

关闭所有页面,打开到应用内的某个页面。

参数

Object object

属性类型默认值是否必填说明支持版本
urlstring
需要跳转的应用内页面路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',如果跳转的页面路径是 tabBar 页面则不能带参数
successfunction
接口调用成功的回调函数
failfunction
接口调用失败的回调函数
completefunction
接口调用结束的回调函数(调用成功、失败都会执行)

wx.reLaunch(),用的不是很多,他有一些版本的兼容(支持版本 >= 1.1.0),刚开始接触这个方法的时候,也试了下,点击“获取用户信息”按钮后跳转到首页,刷新首页的数据信息;我也看了网上的一些项目,也有些人类似的做法,你觉得好吗?个人觉得,关闭所有页面,重新打开跳转,不是那么明智,如果是单纯的想是刷新实时数据,可以用其他的方法,比如在onShow()里使用this.onload()等。当然啦,我们不能说它没用,不然开发出来干啥呢,根据需求来决定吧。下面分享下之前做过的一个项目对于wx.reLaunch()的应用,直接上代码:

<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo">获取授权信息</button>
getUserInfo:function(e){
    console.log('点击加载+'+e)
    app.globalData.userInfo = e.detail.userInfo

      let timer = setTimeout(function () {
        wx.reLaunch({
          url: '/pages/index/index',
          fail: function () {
            Tools.showModal("支付界面  reLaunch调用失败,请重试");
            wx.redirectTo({
              url: '/pages/index/index',
            })
          }
        });

      }, 500) 

      this.setData({
        userInfo: e.detail.userInfo,
        hasUserInfo: true        
      })
}

说明:点击获取用户信息,然后跳转到首页,大家可以参考下。这里要提醒下的是,从上面的代码可以发现我们用了一个定时器(建议使用),也就是跳转到首页需要0.5S的延时,这个是针对页面的一个加载缓存需要时间,比如调用接口的数据等,当然你可以使用loading预加载。

wx.navigateTo(Object object)

保留当前页面,跳转到应用内的某个页面,但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。

参数

Object object
属性类型默认值是否必填说明支持版本
urlstring
需要跳转的应用内非 tabBar 的页面的路径, 路径后可以带参数。参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔;如 'path?key=value&key2=value2'
successfunction
接口调用成功的回调函数
failfunction
接口调用失败的回调函数
completefunction
接口调用结束的回调函数(调用成功、失败都会执行)

wx.navigateTo()用得最多的,可逆转,使用wx.navigateTo接口跳转,原页面保留,这个是跟redirectTo()最大的区别,也就是返回的话,需要一层层的返回,不能跳级返回。具体的用法:

wx.navigateTo({
        //目的页面地址
        url: 'pages/logs/index',
        success: function(res){},
        ...
})

TIPS:跟页面中的A链接差不多。

wx.switchTab(Object object)

跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。

参数

Object object

属性类型默认值是否必填说明支持版本
urlstring
需要跳转的 tabBar 页面的路径(需在 app.json 的 tabBar 字段定义的页面),路径后不能带参数。
successfunction
接口调用成功的回调函数
failfunction
接口调用失败的回调函数
completefunction
接口调用结束的回调函数(调用成功、失败都会执行)

说明:跳转到tabBar带参数会掉坑里,需要特殊处理下。拿个网上案例来说明下:

toCategory:function(event){
    var cate_id = event.currentTarget.dataset.cate_id;
    wx.switchTab({
      url: '../category/category?cate_id='+cate_id,
    });
  },

比如,上面一段正常的传参的代码,按照上面写的在category.js里得不到数据的;

onLoad:function(options){
    console.log(options);
}

所以我们需要按照官方文档,换一种思路来处理。

跳转的时候在全局变量里设置一个变量cate_id,调到category.js中后.调取全局变量里的cate_id,用完后,再把扎个变量清除掉.具体实施如下:

toCategory:function(event){
    var cate_id = event.currentTarget.dataset.cate_id;
    app.globalData.cate_id=cate_id;//设置全局变量(app已经定义 var app=getApp())
    wx.switchTab({
      url: '../category/category'
    });
  },

分类页category.js中写上这一段:

onLoad:function(options){
    var that = this
    var cate_id=app.globalData.cate_id
    wx.request({
      url: app.globalData.httpsurl +'public/index.php?s=product/index',
      data:{
        cate_id:cate_id,
      },
      success:function(res){
        //清除全局变量cate_id
        app.globalData.cate_id=""
        that.setData({
          alldata:res.data,
        })
      }
    })
  },

就可以了。

wx.navigateBack(Object object)

关闭当前页面,返回上一页面或多级页面。可通过getCurrentPages() 获取当前的页面栈,决定需要返回几层。

参数

Object object

属性类型默认值是否必填说明支持版本
deltanumber
返回的页面数,如果 delta 大于现有页面数,则返回到首页。
successfunction
接口调用成功的回调函数
failfunction
接口调用失败的回调函数
completefunction
接口调用结束的回调函数(调用成功、失败都会执行)

注意:调用navigateTo跳转时,调用该方法的页面会被加入堆栈,而redirectTo方法则不会。见下方示例代码:

// 此处是A页面
wx.navigateTo({
    url: 'B?id=1'
})

// 此处是B页面
wx.navigateTo({
    url: 'C?id=1'
})

// 在C页面内 navigateBack,将返回A页面
wx.navigateBack({
    delta: 2
})

navigateBack()也是可以携带参数返回的,我们可以自定义,如何实现呢,看下代码:

let pages = getCurrentPages();//当前页面
let prevPage = pages[pages.length-2];//上一页面
prevPage.setData({//直接给上移页面赋值
  item: e.currentTarget.dataset.item,
  selAddress:'yes'
});
wx.navigateBack({//返回
  delta:1
})

回到上一页,在data里定义item,selAddress,然后在onshow里:

let pages = getCurrentPages();
let currPage = pages[pages.length-1];
 if (currPage.data.selAddress==""){
   that.getUserAddress(that.data.userId);
 }else{
   that.setData({//将携带的参数赋值
     address: currPage.data.item
   });
 }

这只是一个很简单的案例,进一步的知识还要考大家去钻研了。

页面栈

大家可能对上面的一段代码提出疑问,delta是什么东东?OK,这个就相关到另外一个知识点:页面栈。

什么是页面栈呢,简单的说就是页面的层级数,大家都知道,微信小程序最多访问5层,也就是页面栈最多是5。

小程序提供了getCurrentPages()函数获取页面栈,第一个元素为首页,最后一个元素为当前页面。在上面的代码中,有提到过,比如delta:1。

使用wx.navigateTo每新开一个页面,页面栈大小加1,直到页面栈大小为5为止;如果返回页面栈会减1,当然这个只是正常逻辑,有特殊情况?往下看吧。

1、假如使用wx.navigateTo从四级页面跳转到二级页面,此时会在页面栈顶添加一个与二级页面初始状态一样的界面,但两个页面状态是独立的。页面栈大小会加1,如果页面栈大小为5,则wx.navigateTo无效。

2、假如使用wx.redirectTo从四级页面重定向到二级页面,此时会将关闭四级页面,并使用二级页面替换四级页面,但两个页面状态是独立的。此时的页面栈大小不变,请注意和使用wx.navigateTo的区别。

3、假如当前页面为五级页面,使用wx.navigateBack:

  • 当delta为1,关闭五级页面,当前页面为四级页面,页面栈大小减1;

  • 当delta为2,关闭依次五级页面和四级页面,当前页面为三级页面,页面栈大小减2;

  • 以此类推,直到栈底为止,也就是首页。

看上去是不是很蒙蔽,不要紧,这个需要慢慢去了解,建议大家自己做个DEMO,然后每次返回或者进入下一页,打印下页面栈,您就会熟悉了。

总结

小程序应用越来越广,我们需要不断的拓展自己的技术面,才能迎合公司业务的发展速度,否则你会被淘汰。

OK,今天分享的内容有点多,初次了解的童鞋可以多花点心思去研究下,我最近做了一些小程序的项目,如果您不懂的可以咨询,不吝赐教咯,然后可以加入我们的QQ群,或者关注我们的微信公众号。

温馨提示:上述内容难免有疏漏之处,如有大神路过,请多赐教。

>>>> 国庆和中秋就要来了,最后祝福大家节日快乐,玩的开心,出行注意安全,一定不要霸座哟(^U^)ノ~YO

您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/xcxluyou20180920.html

网友评论文明上网理性发言 已有0人参与

发表评论: