关于小程序页面栈的问题

黄粱一梦2024-03-0111

先说一下触坑场景吧

a页面 -> b页面 -c页面 -> a页面

前提都是使用uni.navigateTo()进行的跳转,然后就在这时候出现问题了,在上一个页面绑定了uni.$emit()事件然后在a页面触发事件修改this页面内值发现无效然后搞了半天想起来可能是小程序页面栈内存问题 修改的变量数据不是原来的数据了!!!

小程序页面栈

在做小程序项目的时候不难发现,使用navigateTo进行页面跳转后,点击左上角或使用navigateBack返回,总是会按照之前的页面进入倒序来展示页面,那么问题来了,它们的跳转规则是什么样的呢?结合到实际业务中如何灵活运用呢?

什么是小程序页面栈?

首先先来了解一下微信小程序的运行环境:
小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。

小程序官方页面路由文档

  • navigateTo, redirectTo 只能打开非 tabBar 页面。
  • switchTab 只能打开 tabBar 页面。
  • reLaunch 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数可以在目标页面的onLoad中获取。

Description

我们可以看到,一个页面使用一个 WebView 线程进行渲染。如果打开10个页面,则会开启 10 个 WebView 线程,此时内存中的十个webView线程我们称之为页面栈。当然小程序也会对这块内存做限制,目前页面栈的限制是不能超过十条。在小程序中页面的路由是小程序框架本身控制的我们不要去手动管理, 小程序框架通过一个页面栈的设计来管理所有的界面,当发生路由跳转时,页面栈就会做出相应的变化,在小程序页面中通过 getCurrentPages() 就可以获取到当前的页面栈。

页面栈实际应用分析

下面我们分析一下页面栈的变化过程,从分析中,我们需要明白的一个重要问题就是,当客户按返回按钮的时候究竟会跳转到那个界面,这是我们分析页面栈变化的的意义。 首先我们在页面中调用两次navigateTo,页面栈情况如下

这时显示的界面是pageC ,如果客户在此时返回则会一切正常,回退的第一个界面是pageB,然后是pageA。但是如果在pageC 界面调用 wx.redirectTo({url:‘pageD’}) 则情况就会不一样,我们先看一下跳转到pageD后页面栈的情况如何。

如图所示栈中出现了两个相同的pageB界面,这个时候如果用户按退出键就会出现一个页面出现2次的情况,而且有一个界面的数据也是旧的数据。因此为了避免这个问题,我们应该在 PageC 页面避免将 PageB重复压入栈中,所以在pageC页面使用wx.navigateBack({delta:1}); 进行页面回退。而数据刷新的问题则在页面的onShow函数中进行即可。

:::danger
微信官方不建议修改页面栈
:::

虽然这种方法简便,但是官方也给出提醒,页面栈数据可以自行修改,但是!一定要慎重,否则会导致页面状态错误。

参考文章:
原文链接·掘金地址
作者:优孤

分类:前端小程序

标签:前端uniapp小程序

上一篇解决ERROR in Conflict: Multiple assets emit different content to the same filename index.html 的问题下一篇uni-app setTabBarBadge在非tabBar页面设置时无法生效

版权声明

本文系作者 @黄粱一梦 转载请注明出处,文中若有转载的以及参考文章地址也需注明。\(^o^)/~

Preview