微信小程序——页面栈及路由跳转

时间:2024-05-19 10:53:50

引言

近期在开发微信小程序,在此之前,我看过微信小程序官方的文档,了解过小程序的开发模式,简单写过一些 Demo。然后,在写代码的过程中,遇到了页面栈的关闭、打开问题,其实也是一个老朋友。很早之前,在开发混合 APP 的时候,我就遇到类似的问题。所以,这次详细地认识一下页面的跳转方式。

首先,在小程序中,路由是由一个栈维护的,这个页面栈的长度是有限的。也就是说,如果你在栈满的情况下(小程序中页面栈最多为10),还使用 navigateTo 进行路由的跳转,此时就会待机,因为入不了栈了。所以,在平常开发中,我们需要注意路由的跳转和页面栈的情况。

官方文档也描述在一些跳转的时候,页面栈会发生的变化:
微信小程序——页面栈及路由跳转
那么,接下来我们看看官方提供的4种路由跳转 API 是怎样命中上面的这些逻辑的。

PS:在阅读的时候,大家需要分清非 Tab 页面和 Tab 页面,不要弄混了~

switchTab

switchTab 只能跳转到 tab 页面,并且它还会关闭其他非 tab 页面。所以,swichTab 进行 tab 页的跳转就会命中 Tab 切换的逻辑,此时页面全部出栈,新的 tab 页入栈。

使用 switchTab 进行 Tab 页之间的跳转(即 Tab 页跳 Tab 页)完全没有问题。但是如果此时我页面栈中的情况是这样的,栈底是一个 Tab 页(A),栈顶为一个非 Tab 页,此时页面的展示为 这个非 Tab 页,那么现在调用 switchTab 在这个非 Tab 页跳其他 Tab 页(B),页面栈会将页面(Tab 和 非 Tab)全部出栈,新的 Tab 页(B)入栈,与此同时对应的页面的表现形式会先看到 Tab 页(A),然后再到 Tab 页(B)。

这个过程无疑,不是我们想要的,所以,非 Tab 页在使用 switchTab 进行 Tab 页跳转其他 Tab 页的时候,要注意之前是否存在 Tab 页未关闭(即未出栈)。

reLaunch

reLaunch 可以跳转到任何页面(Tab 页或非 Tab 页),并且它会关闭其他所有页面。它会命中重加载的逻辑,即页面全部出栈,新的页面(Tab 页或非 Tab 页)入栈。

所以,大家可以想到的是当你走投无路的时候,你就可以用 reLaunch 进行骚操作。但是,从性能的角度出发,reLaunch 如果不适合你的使用场景,还是少用。因为,如果每一次路由的跳转都是通过 reLaunch,那么意味每一次打开一个页面都是重新绘制的,这样用户体验肯定不好。所以,reLauch 虽然可以解决所有路由跳转问题,但是还是需要从使用场景出发正确地使用。

redirectTo

redirectTo 可以进行非 Tab 页的跳转,并且它会关闭此时的页面。它会命中重定向的逻辑,即当前页面出栈,新页面(非 Tab 页)入栈。

对于 rediectTo,需要注意的是如果你的新打开的页面(非 Tab 页)需要返回上一个打开问的页面,你如果用了它,那就待机,因为上一个页面已经不在页面栈中了,此时你返回的可能是上上个页面。所以,对于需要返回上个页面的路由跳转,rediectTo 并不适合。

navigateTo

naviagteTo 可以进行非 Tab 页的跳转,它不会影响到任何其他页面。它会命中打开新页面的逻辑,即新页面(非 Tab 页)入栈。

对于 navigateTo,需要注意的是别一股脑地使用 navigateTo,由于它是新页面入栈,很可能不知不觉页面栈就被你搞满了,此时你就死在这个页面了。所以,对于一些不需要返回的路由跳转,我们并不需要使用 navigateTo,反正,我们可以使用。

navigateBack

navigateBack 可以进行任何页面的返回,它是一个匹配的过程。它会命中打开返回页面的逻辑,即页面不断出栈,直到目标页面。

对于 navigateBack,需要注意的是你得先知道你要跳的页面所在的栈的层级,页面栈我们可以用 getCurrentPages() 获取(需要注意的是,不要再onLauch 的时候调用)。然后,通过指定 delta 参数跳转对应的页面。但是,需要注意的是,此时你页面栈中当前页面不是处于栈底,如果这样你想返回上一层级的路由,显然是无效的操作,因为此时页面栈中不存在上一级。所以,在使用 navigateBack 的时候,也需要注意一下此时页面栈的长度。

总结

在小程序进行页面路由的跳转,你需要理清哪些页面需要关闭跳转,哪些页面不需要关闭跳转,因为如果路由跳转方式选择不好,很可能就会造成不好的用户体验,甚至还可能写出无效的路由跳转。