页面特效 UI组件库 菜单导航 窗口特效 幻灯片滑动 图像相册 表单 选项卡 表格 评分星级 手风琴 文本链接 布局 日历 颜色选择器 按钮 图表 html5 提示 ExtJS 在线客服 其他特效 地图 树形控件 移动开发 BootStrap 滑动条 文件上传 表单验证 分页 播放器 Angular VUE
官方客服QQ号:3007971137  (一条龙搭建-联系我)
官方客服QQ号:3007947123  (一条龙搭建-联系我)

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

页面特效 技术03-千编万码 3月前  次浏览

什么是小程序里的“路由”?路由器吗?蒙蔽?好吧,在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

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

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

不懂?来看个例子。

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

						
						
						
  1. wx.redirectTo({
  2. //目的页面地址
  3. url: 'pages/index/index',
  4. success: function(res){
  5. },
  6. ...
  7. })

wx.reLaunch(Object object)

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

参数

Object object

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

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

												
												
												
  1. wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo">获取授权信息

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

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

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

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

wx.switchTab(Object object)

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

参数

Object object

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

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

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

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

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

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

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

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

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

																					
																					
																							
  1. onLoad:function(options){
  2. var that = this
  3. var cate_id=app.globalData.cate_id
  4. wx.request({
  5. url: app.globalData.httpsurl +'public/index.php?s=product/index',
  6. data:{
  7. cate_id:cate_id,
  8. },
  9. success:function(res){
  10. //清除全局变量cate_id
  11. app.globalData.cate_id=""
  12. that.setData({
  13. alldata:res.data,
  14. })
  15. }
  16. })
  17. },

就可以了。

wx.navigateBack(Object object)

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

参数

Object object

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

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

																												
																												
																														
  1. // 此处是A页面
  2. wx.navigateTo({
  3. url: 'B?id=1'
  4. })
  5. // 此处是B页面
  6. wx.navigateTo({
  7. url: 'C?id=1'
  8. })
  9. // 在C页面内 navigateBack,将返回A页面
  10. wx.navigateBack({
  11. delta: 2
  12. })

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

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

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

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

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

页面栈

大家可能对上面的一段代码提出疑问,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群,或者关注我们的微信公众号。

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

相关链接

发表评论