《微信小程序开发之路由思考》

路由概述

小程序框架使用栈的形式来维护了所有展示页面,当页面进行打开、前进、返回、关闭、tab切换等操作时,都是页面的不断出栈进栈的过程。当然这个栈的层级是有数量限制的,官方规定最多5层页面,多了之后将无法打开下一级的页面。
需要说明一点的是官方提供了navigator这个组件wx.navigateTo()wx.redirectTo()等多个方法来供开发者来实现实现的页面的跳转,重定向。而且两者是有对应关系的,下面来简单描述一下,更详细的讲解请查阅官方API文档。

导航API方法

小程序官方提供了5种导航方式,其中4种都带有丰富的回调接口满足开发者的使用。

  • wx.navigateTo(object):保留当前页面(栈),跳转到另外某个页面(新进栈)。注意当前页面不会出栈,下个页面使用wx.navigateBack可以返回到该页面。

    1
    2
    3
    4
    5
    6
    wx.navigateTo({
    url: 'test?id=1', //不能是tabBar里定义过的链接
    success: function(){ ... },
    fail: function(){ ... },
    complete: function(){ ... }
    })
  • wx.redirectTo(object):关闭当前页面(出栈),跳转到另外某个页面(新进栈)。

    1
    2
    3
    4
    5
    6
    wx.redirectTo({
    url: 'test?id=1', //不能是tabBar里定义过的链接
    success: function(){ ... },
    fail: function(){ ... },
    complete: function(){ ... }
    })
  • wx.reLaunch(object):关闭其他所有栈内的页面,打开到某个页面(唯一在栈内页面)。调用该方法,左上角返回箭头也会消失。

    1
    2
    3
    4
    5
    6
    wx.reLaunch({
    url: 'test?id=1',
    success: function(){ ... },
    fail: function(){ ... },
    complete: function(){ ... }
    })
  • wx.switchTab(object): 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

    1
    2
    3
    4
    5
    6
    wx.reLaunch({
    url: 'test?id=1', //需在app.json中定义过
    success: function(){ ... },
    fail: function(){ ... },
    complete: function(){ ... }
    })
  • wx.navigateBack(object):关闭当前页面,返回上一页面或多级页面。可通过getCurrentPages()获取当前的页面栈,决定需要返回几层。接受唯一参数delta

    1
    2
    3
    wx.navigateBack({
    delta: 2
    })
wx.navigateTo 和 wx.redirectTo 不允许跳转到 tabbar 页面,只能用 wx.switchTab 跳转到 tabbar 页面

这个组件或者说标签是用在 .wxml文件中的,其实就相当于一个带href属性的a标签

1
<navigator url="/page/index/index" open-type="navigate" hover-class="other-navigator-hover">切换 Tab</navigator>

最常用的属性有:url指向要跳转的链接;open-type定义跳转的方式,这个马上下面介绍;hover-class规定点击该标签时的样式类。
open-type有5个有效值:

  • navigate:对应于wx.navigateTo()
  • redirect:对应wx.redirectTo()
  • switchTab:对应wx.switchTab()
  • reLanch:对应wx.reLaunch
  • navigateBack:对应wx.navigateBack

实际使用

navigator组件和wx.navigateTo()等方法其实是一样的,需要具体情况具体分析选择,做几个页面其实基本上就可以掌握用法。我这次做到的项目中,具体是这样的一种页面层级关系:

1
2
3
4
5
6
<!-- tab1首页 -->
index ==> goodsList ==> goodsInfo ==> buy(redirectTo) ==> orderList
(1) (2) (3) (4)
<!-- tab2我的 -->
userInfo ==> orderList
(1) (2)

其中goodsInfo页面有一个直达orderList的按钮,tabBar中我的页面有个人订单项,可以查看我的订单。
有一个需求是在orderList页面中实现点击商品跳转至对应的goodsInfo页面,这样其实形成了一种闭环的页面跳转,如果直接使用wx.navigateTo()方法,则新打开的goodsInfo页面便会是第五层,其中的任何链接将无法再点击打开;如果使用wx.redirectTo()打开,则用户无法通过右滑再次返回orderList页面,用户体验不好。
思考最后,最终的解决方案是在orderList页中为商品绑定点击事件,通过getCurrentPages()获取当前层级,若层级大于2,则return掉点击事件,同时新做了一个订单详情的页面作为备选方案,可以查看订单的一些信息;若层级等于2,则点击商品跳转至对应的商品详情goodsInfo页中。

1
2
3
4
5
6
7
8
toGoodsInfo: function(){
let pages = getCurrentPages();
if(pages.length == 2){
wx.navgateTo({
url: `/pages/goodsInfo/goodsInfo?id=${this.goods.id}`
})
}
}