uni-app:PageStack页面栈

页面栈(Page Stack)概念

UniApp 使用一个栈结构(Last In First Out)来管理页面:

页面栈示意图:
栈顶 → [详情页]  ← 当前显示的页面
      [列表页]
      [首页]
栈底 → [启动页]

五种跳转方式的技术解析

uni.navigateTo() - 压栈操作

// 执行前
栈:[首页, 列表页]

// 执行 uni.navigateTo({ url: '/pages/news/detail' })
栈:[首页, 列表页, 详情页]  ← 新页面压入栈顶

// 此时:
- 首页:保持原样,仍在内存中
- 列表页:保持原样,仍在内存中
- 详情页:新加载,显示
- 返回时:详情页出栈,显示列表页

本质:将新页面实例压入页面栈顶,原页面实例保留在栈中,所有页面数据状态维持不变

uni.redirectTo() - 替换栈顶操作

// 执行前
栈:[首页, 列表页]  ← 列表页在栈顶

// 执行 uni.redirectTo({ url: '/pages/login/login' })
栈:[首页, 登录页]  ← 列表页被移除,登录页放入

// 此时:
- 首页:保持原样
- 列表页:被销毁(触发了 onUnload)
- 登录页:新加载
- 返回时:直接回到首页,无法回到列表页

本质:将当前栈顶页面销毁(释放内存),用新页面替换它的位置。

uni.reLaunch() - 重置整个栈

// 执行前
栈:[启动页, 首页, 列表页, 详情页]  ← 4个页面

// 执行 uni.reLaunch({ url: '/pages/index/index' })
栈:[首页]  ← 只有新页面

// 此时:
- 所有原页面(启动页、首页、列表页、详情页)全部销毁
- 新首页:重新加载
- 返回时:无法返回,因为栈底只有首页

本质:清空整个页面栈,销毁所有页面实例,创建新页面作为根页面。

uni.switchTab() - 特殊栈操作

// 假设 tabBar 配置了:首页、分类、购物车、个人
// 执行前
栈:[商品详情, 分类, 首页]  ← 有3个页面

// 执行 uni.switchTab({ url: '/pages/user/user' })
栈:[个人]  ← 清除非 tabBar 页面,保留 tabBar 页面单例

// 此时:
- 非 tabBar 页面(商品详情)被销毁
- 个人页如果是首次打开:创建新实例
- 个人页如果之前打开过:复用之前的实例(保持原有状态)

本质:维持 tabBar 页面的单例模式,清空所有非 tabBar 页面。

uni.navigateBack() - 弹栈操作

// 执行前
栈:[首页, 列表页, 详情页]  ← 3个页面

// 执行 uni.navigateBack({ delta: 1 })
栈:[首页, 列表页]  ← 详情页出栈并销毁

// 执行 uni.navigateBack({ delta: 2 })
栈:[首页]  ← 列表页和详情页都出栈并销毁

本质:将栈顶的 n 个页面弹出并销毁,显示前一个页面。

内存管理角度

跳转方式 原页面状态 内存处理 适用场景
navigateTo 保留(挂起) 占用内存,保留数据 详情页、表单填写页
redirectTo 销毁 释放内存 登录页、支付中间页
reLaunch 全部销毁 完全释放 退出登录、切换账号
switchTab 选择性保留 维护 tab 实例 底部导航切换
navigateBack 销毁返回的页面 逐步释放 返回操作

生命周期验证

可以通过页面的生命周期函数来验证这些行为:

// 在页面中
onLoad() { console.log('页面加载', this.$route) }
onShow() { console.log('页面显示', this.$route) }
onHide() { console.log('页面隐藏', this.$route) }
onUnload() { console.log('页面销毁', this.$route) }

// navigateTo: 新页面 onLoad → onShow,原页面 onHide
// redirectTo: 原页面 onUnload,新页面 onLoad → onShow
// reLaunch: 所有页面 onUnload,新页面 onLoad → onShow
// navigateBack: 当前页 onUnload,前一页 onShow

这就是为什么说 navigateTo 是”保留”(页面实例依然存在,只是被隐藏),而 redirectTo 是”关闭”(页面实例被彻底销毁,无法再回来)。

参数

uni.navigateTo(OBJECT)

这是最常用的跳转方式,参数也最丰富:

  • url (String | 必填):目标页面路径,支持带参数,如 '/pages/detail/detail?id=1'
  • animationType (String | 否):窗口显示的动画效果(仅App平台支持),如 "pop-in""slide-in-right"
  • animationDuration (Number | 否):动画持续时间,单位毫秒(仅App平台支持),默认 300
  • events (Object | 否):页面间通信接口,可以监听被打开页面发送的事件。
  • success (Function | 否):跳转成功的回调。
  • fail (Function | 否):跳转失败的回调。
  • complete (Function | 否):跳转结束(成功或失败都会执行)的回调。

uni.redirectTo(OBJECT)

参数相对简洁:

  • url (String | 必填):目标页面路径,可带参数,但不能是 tabBar 页面。
  • success (Function | 否):跳转成功的回调。
  • fail (Function | 否):跳转失败的回调。
  • complete (Function | 否):跳转结束的回调。

uni.reLaunch(OBJECT)

用于“重启式”跳转:

  • url (String | 必填):目标页面路径,可带参数。特别注意:如果跳转到 tabBar 页面,则不能带参数
  • success (Function | 否):跳转成功的回调。
  • fail (Function | 否):跳转失败的回调。
  • complete (Function | 否):跳转结束的回调。

uni.switchTab(OBJECT)

专用于底部导航栏页面:

  • url (String | 必填):目标 tabBar 页面的路径,路径后不能带参数
  • success (Function | 否):跳转成功的回调。
  • fail (Function | 否):跳转失败的回调。
  • complete (Function | 否):跳转结束的回调。

uni.navigateBack(OBJECT)

用于返回操作:

  • delta (Number | 否):返回的页面层数,默认 1。如果数字大于页面栈深度,则返回到首页。
  • animationType (String | 否):窗口关闭的动画效果(仅App平台支持),如 "pop-out"
  • animationDuration (Number | 否):动画持续时间,单位毫秒(仅App平台支持),默认 300
  • success (Function | 否):返回成功的回调。
  • fail (Function | 否):返回失败的回调。
  • complete (Function | 否):返回结束的回调。

×

喜欢就点赞,疼爱就打赏