在微信小程序开发中,页面跳转是实现用户交互的核心功能之一。不同的跳转方式对应不同的业务场景,而**页面栈**则是理解跳转逻辑的关键概念。以下是关于 `navigateTo`、`redirectTo`、`reLaunch` 以及页面栈的详细说明: ### **一、页面栈(Page Stack)** #### **1. 概念** - 微信小程序的页面管理基于**栈结构**(后进先出),每个页面实例会被压入栈中,称为“页面栈”。 - 栈的最大层数限制为 **10层**,超过时会报错(`navigateTo:fail webview count limit`)。 #### **2. 常见操作与栈变化** | 操作类型 | 栈变化描述 | 示例场景 | |----------------|-------------------------------------|------------------------------| | **初始化** | 打开第1个页面,栈中压入1个页面实例 | 小程序启动进入首页 | | **跳转** | 压入新页面实例,栈深度+1 | `navigateTo` 跳转到新页面 | | **返回** | 弹出当前页面,栈深度-1 | `navigateBack` 或左上角返回按钮 | | **替换** | 弹出当前页面,压入新页面(栈深度不变) | `redirectTo` 跳转 | | **重置** | 清空栈,压入新页面(栈深度为1) | `reLaunch` 或 `switchTab` 跳转 | ### **二、跳转API对比** #### **1. navigateTo(保留当前页跳转)** - **API格式**:`wx.navigateTo({ url: '页面路径' })` - **特点**: - **保留当前页面**,跳转至新页面,新页面入栈(栈深度+1)。 - 可通过 `navigateBack` 或左上角返回按钮回到当前页。 - **不能跳转到 tabBar 页面**(需用 `switchTab`)。 - **适用场景**:多级页面跳转(如首页 → 详情页 → 编辑页)。 **示例**: ```javascript // 从 A 页面跳转到 B 页面 wx.navigateTo({ url: '/pages/B/B' }); // 此时页面栈:[A, B] ``` #### **2. redirectTo(关闭当前页跳转)** - **API格式**:`wx.redirectTo({ url: '页面路径' })` - **特点**: - **关闭当前页面**,跳转至新页面,新页面替换当前页(栈深度不变)。 - **无法通过返回按钮回到原页面**(原页面已出栈)。 - **不能跳转到 tabBar 页面**(需用 `switchTab`)。 - **适用场景**:流程型操作(如登录成功后跳转到主页,不再需要返回登录页)。 **示例**: ```javascript // 从 A 页面跳转到 B 页面(关闭 A) wx.redirectTo({ url: '/pages/B/B' }); // 此时页面栈:[B] ``` #### **3. reLaunch(重启应用后跳转)** - **API格式**:`wx.reLaunch({ url: '页面路径' })` - **特点**: - **清空整个页面栈**,重新加载目标页面(栈深度为1)。 - **无论当前页面在哪,都会强制跳转到目标页**,且可跳转到 tabBar 页面。 - **适用场景**:需要重置应用状态(如退出登录后回到登录页,清除所有历史记录)。 **示例**: ```javascript // 从任意页面跳转到首页(清空栈) wx.reLaunch({ url: '/pages/index/index' }); // 此时页面栈:[index] ``` ### **三、与其他跳转方式的对比** | 特性 | navigateTo | redirectTo | reLaunch | switchTab | |--------------------|------------------|------------------|------------------|------------------| | **是否保留原页面** | 是(压入新页) | 否(替换原页) | 否(清空栈) | 否(清空非 tab 页) | | **能否跳转到 tabBar** | 否 | 否 | 是 | 是 | | **页面栈深度变化** | +1 | 不变 | 重置为1 | 保留 tab 页,清空其他 | | **返回按钮是否可用** | 是 | 否(原页已关闭) | 否(无历史记录) | 是(可切换 tab) | ### **四、注意事项** 1. **栈深度限制**:避免多层 `navigateTo` 跳转导致栈溢出,可通过 `reLaunch` 或 `redirectTo` 清理栈。 2. **tabBar 页面跳转**: - 跳转到 tabBar 页面需用 `switchTab` 或 `reLaunch`。 - `switchTab` 会保留 tabBar 页面,但清空其他非 tab 页面的栈。 3. **生命周期钩子**: - `navigateTo` 跳转时,原页面触发 `onHide`,新页面触发 `onLoad`/`onShow`。 - `redirectTo`/`reLaunch` 跳转时,原页面触发 `onUnload`,新页面触发 `onLoad`/`onShow`。 ### **五、最佳实践** - **多级页面导航**:使用 `navigateTo` 实现页面层层递进,允许用户返回。 - **流程终点跳转**:如表单提交后,用 `redirectTo` 跳转到结果页,避免重复提交。 - **状态重置场景**:如用户登出,用 `reLaunch` 跳转到登录页,清除所有业务状态。 - **tabBar 切换**:直接使用 `switchTab` 跳转到 tab 页面,保持底部导航栏显示。 通过合理选择跳转方式和管理页面栈,可以优化小程序的用户体验和性能。