随着小程序被微信团队快速铺开,小程序对于产品吸引力和产品给予小程序的预期也越来越高,那么使用小程序开发的业务产品可能跟小程序本身最先给自己的定位已经慢慢偏离啦。
我们知道在最早小程序的定位中,一个比较高频的词汇是【用完即走】,那么意味着它对于产品的预期是业务逻辑足够简单,不要过多地页面跳转,过多的页面跳转意味着用户不能更直接、更方便地获取自己的诉求。
对这个特性体现比较明显的产品比如“车来了”,2层页面深度,用户能够在这2层页面上完成自己查看公交的诉求,非常明了。
但是,有些假设产品的业务嵌套必然(或可能)超出5层的时候怎么处理呢?很不幸的是我们目前在开发的产品一条业务线走下去一定会超出5层!(手动捂脸)
我们先一起看看小程序路由的几种方式和对小程序框架维护的路由栈的影响。
小程序路由跳转方式(以同一个tab内的路由为例)
- navigateTo:跳转前当前页面入路由栈,如果当前栈数目已经达到5个,则跳转到目标页面失败;如果未达到5个,则跳转目标页面,且目标页面入栈
- redirectTo:跳转前当前页面出路由栈,跳转到目标页面,并且目标页面入路由栈
- reLaunch:跳转前清空路由栈,跳转到目标页面,并且目标页面入路由栈
- navigateBack:执行指定次数的退栈操作,默认回退一层,显示目标页面
我们可以用下列图示来说明上面的路由跳转影响,假设我们有以下路径
那么,根据上图的页面访问路径在不同的跳转方式跳转路由时产生的结果如下所示
跳转动作 | 结果&路由栈 |
---|---|
访问首页(A) | 跳转成功,栈:[ A ] |
navigateTo(B) | 跳转成功,栈:[ A , B ] |
navigateTo(C) | 跳转成功,栈: [ A , B , C ] |
redirectTo(D) | 跳转成功,栈:[ A , B , D ] |
reLaunch(A) | 跳转成功,栈:[ A ] |
navigateTo(B) | 跳转成功,栈:[ A , B ] |
navigateTo(C) | 跳转成功,栈: [ A , B , C ] |
navigateTo(D) | 跳转成功,栈: [ A , B , C , D ] |
navigateTo(E) | 跳转成功,栈: [ A , B , C , D , E ] |
navigateTo(F) | 跳转失败,栈: [ A , B , C , D , E ] |
从上面的整个跳转逻辑的测试中,发现一个很明显的问题,当路由栈中路由的数目达到它规定的最大的数量5时,再使用navigateTo进行跳转时页面跳转会失败。
但是,开发者如何知道何时不能使用navigateTo方式来路由呢?
然后,再看另外一个问题,以如下的路由场景为例进行说明
跳转动作 | 结果&路由栈 |
---|---|
访问首页(A) | 跳转成功,栈:[ A ] |
navigateTo(B) | 跳转成功,栈:[ A , B ] |
redirectTo(A) | 跳转成功,栈:[ A , A ] |
navigateTo(B) | 跳转成功,栈:[ A , A , B ] |
redirectTo(A) | 跳转成功,栈:[ A , A , A ] |
把上述的动作进行一个循环操作以后发现栈里面会被路由A占满,但是这种操作场景是非常常见的。比如,我们在A页面上有个查看文档或者去B页面配置某些数据,然后回到A页面。如果用户多操作几次,不经意间,栈炸了...
小程序从设计初衷上来讲,肯定是不希望产品的设计会嵌套这么多层,但是作为产品开发的服务者,很多时候情形都不是那么乐观,刚好我们的产品就是需要多层路由,刚好我们就是它的开发者,刚好我们就碰到了上述的一些问题。所以,在目前的情况下,我们还是得去对微信小程序的路由进行一些封装,在调用的时候能够智能地做一些分析。
封装的目标
- 解决navigateTo跳转时栈满的情况下路由失效的问题
- 解决循环跳转栈内大量重复无价值的路由数据
- 提升页面数据交互、传递的便捷性(加分项)
基于此,我们对于整个路由的封装基本思路就出来了:所有的路由都走一个方法,通过指定路由的类型来映射到相应的路由的action,具体action在进行路由之前做统一智能判断和方案决策;在路由系统内部会维护一个内部的以路由绝对地址为key的数据对象。
路由从统一入口进入后被控制器捕获,控制器根据开发者设置的路由类型将路由分发到对应的Action操作,对应的数据会交给组装器进行组装,并且会判断当前路由栈数据的情况。如果栈满5层,那么就将路由硬转为redirctTo的方式并交给小程序路由器完成路由;如果存在路由出栈、入栈后栈顶出现相邻相同路由,则将路由的方式智能切换为navigaBack方式,以此来节约路由栈资源。
当然,这也会带来一些问题
- 路由被硬转为redirectTo的方式跳转的话,用户点击返回按钮则不会回到上一个实际操作的页面
- 以navigateBack的方式返回到上一个页面时,开发者要对页面的数据是否需要刷新有个非常清晰地认知,如果数据需要刷新的话开发者则应在onShow事件中刷新数据
总而言之,整个小程序页面跳转、加载、刷新等都需要开发者对每个用户行为触发哪些相应的变化有比较深入的了解,在了解它的不足的基础上去尽量避免带来的产品体验断层、甚至是不可操作的重大bug等问题。上述方案不是完美方案,但是在保证基本服务的基础上对于开发者、对于产品体验的保证是一个不错的选择。
希望能有更多的讨论。