uni-app x 应用路由事件监听与路由重写:onBeforeAppRoute、onAppRoute、rewriteRoute 实战指南
2026/9/20 18:27:14 网站建设 项目流程

uni-app x 应用路由事件监听与路由重写:onBeforeAppRoute、onAppRoute、rewriteRoute 实战指南

【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app

应用路由事件是 uni-app x 从应用级别监听主页面路由开始与完成、并在路由真正执行前重写目标页面的能力,适用于路由上报、全局状态重置、访问控制、无效入口页纠正与页面迁移等"一次路由"级逻辑。本文将基于官方文档完整讲解uni.onBeforeAppRouteuni.onAppRouteuni.offBeforeAppRouteuni.offAppRouteuni.rewriteRoute五个 API 的时序、触发场景、事件参数、平台差异与重写规则,并给出可直接运行的 UTS/Vue 示例,帮助你掌握在 Web、App(Android/iOS/HarmonyOS)与微信、支付宝等小程序端统一进行路由拦截和重定向的实战方案。

应用路由事件概述

应用路由事件用于从应用级别监听主页面路由的开始和完成,也可以在路由真正执行前重写目标页面。

它适合处理以下与"一次路由"相关的逻辑:

  • 路由上报:统计每次路由的目标页面、路由类型与参数;
  • 全局状态重置:路由切换时清理或初始化全局数据;
  • 访问控制:在路由执行前判断登录态、权限,未通过时重写路由;
  • 无效入口页纠正:应用被直接启动到不存在的页面时,重定向到有效页面;
  • 页面迁移:旧页面地址迁移到新页面地址。

如果逻辑只与单个页面的创建、显示或销毁有关,应优先使用对应的页面生命周期。例如onLoad只在新页面创建时触发一次、onShow在页面每次显示时触发,二者与页面实例的创建销毁强绑定;而应用路由事件是应用级的、面向"一次路由"的横切逻辑,二者定位不同,应根据业务归属选择。

应用路由事件只作用于主页面路由。dialogPage 的打开、关闭以及随所属页面销毁,均不会触发本页 API。这与 dialogPage 的设计一致:dialogPage 不使用uni.navigateTo等路由 API,而是单独提供openDialogPagecloseDialogPage,不影响页面栈和路由地址,因此也不参与应用路由事件的派发。

API 列表

API说明
uni.onBeforeAppRoute监听路由执行前的事件
uni.offBeforeAppRoute取消监听路由执行前的事件
uni.onAppRoute监听路由成功后的事件
uni.offAppRoute取消监听路由成功后的事件
uni.rewriteRoute在路由执行前重写本次路由

事件时序

一次成功路由的主要执行顺序如下:

发起路由 -> 解析路径并校验目标 -> onBeforeAppRoute -> 执行路由逻辑 -> 目标页面 onShow -> onAppRoute -> 路由转场动画完成

新页面创建时,相关事件和页面生命周期的顺序为:

onBeforeAppRoute -> onLoad -> onShow -> onAppRoute

返回已有页面或切换到已存在的 tabBar 页面时,不会再次触发onLoad,顺序为:

onBeforeAppRoute -> onShow -> onAppRoute

这里与页面生命周期中的说明相互印证:onLoad只在页面创建时触发一次,而页面从隐藏恢复显示时只触发onShow

关键时点语义:

  • onBeforeAppRoute在页面栈变化以及页面创建、销毁等实际副作用发生触发;
  • onAppRoute在路由成功且目标页面的onShow执行触发,不等待路由转场动画完成。

触发场景

下表列出了各场景下两个事件与"可重写"的情况:

场景onBeforeAppRouteonAppRoute可重写
应用启动并进入有效首页或二级页面触发路由成功后触发
应用直接启动到不存在的页面触发,notFoundtrue;支付宝小程序固定为false未重写时按缺页流程触发;支付宝小程序不触发支持rewriteRoute的平台可重写
navigateToredirectToreLaunch成功触发路由成功后触发
切换到其他 tabBar 页面触发路由成功后触发是,且目标必须是 tabBar 页面
switchTab到当前 tabBar 页面不触发不触发
navigateBack、系统返回、返回手势或 Web History 后退触发路由成功后触发
路由 API 参数错误或目标页面校验失败不触发;支付宝小程序仍会触发,且notFoundfalse不触发
onBeforeAppRoute已触发,但路由随后取消或执行失败已触发不触发仅可在同步回调阶段重写
应用从后台恢复,但主页面路由未变化不触发不触发
dialogPage 打开、关闭或随所属页面销毁不触发不触发

两点需要特别留意:

  1. 监听器注册前已经发生的事件不会补发。如需监听或重写appLaunch,应在onLaunch生命周期中或之前尽早注册监听器。
  2. 正常调用路由 API 时,参数错误或目标页面不存在会直接失败;除支付宝小程序外,此类失败不会产生应用路由事件。notFound主要用于应用直接启动到不存在页面等已经进入路由流程的场景。

事件参数与路由类型

onBeforeAppRouteonAppRoute的公共事件参数含义如下:

属性说明
path目标页面路径,不包含开头的/
query当前轮路由解析得到的页面参数
openType路由类型。发生重写时保持原路由类型不变
notFound当前目标页面是否不存在
routeEventId应用实例内唯一的路由事件标识

onAppRoute还会提供timeStamp,表示当前轮路由事件生成时的时间戳。

不同平台可能提供额外的事件字段。编写跨平台代码时,应只依赖上述公共字段。

routeEventId的关联规则:未发生重写时,同一次路由的onBeforeAppRouteonAppRoute使用相同的routeEventId;每次成功重写都会生成新的路由事件和新的routeEventId,最终的onAppRoute使用最后一轮onBeforeAppRouterouteEventId

路由类型(openType)

openType路由来源
appLaunch应用首次启动;Web 直接访问首页或二级页面等入口路由
navigateTouni.navigateTo;Web History 前进;无法识别为其他类型的新增页面路由
navigateBackuni.navigateBack;系统返回、返回手势;Web History 后退;小程序系统返回
redirectTouni.redirectTo
reLaunchuni.reLaunch
switchTabuni.switchTab;用户切换到其他 tabBar 页面

平台差异与版本要求

::: warning 平台差异

  • 微信小程序的路由事件监听要求基础库3.5.5及以上版本;rewriteRoute要求基础库3.8.0及以上版本,并受微信客户端版本、运行平台和分包限制。微信开发者工具模拟器不支持rewriteRoute,应在支持该能力的真机环境中验证。
  • 支付宝小程序通过my.createRouteObserver实现路由事件监听。支付宝小程序开发者工具目前未提供my.createRouteObserver,无法在开发者工具中验证路由事件监听相关 API,应在支持该能力的支付宝客户端真机环境中验证。支付宝的前置事件不提供目标页面是否存在的信息,因此onBeforeAppRoutenotFound固定为false。当路由 API 的目标页面不存在时,支付宝仍会触发onBeforeAppRoute,但不会触发onAppRoute;应用直接启动到不存在的页面时同样不会触发onAppRoute。支付宝小程序暂不支持rewriteRoute

:::

从版本记录看,本仓库的 release-note-alpha.md 明确记载了"新增 API uni.onAppRoute、uni.onBeforeAppRoute、uni.rewriteRoute 支持页面路由监听及重写"这一能力(对应 issue 31599),说明该系列 API 属于 uni-app x 的较新能力,使用时建议保持 HBuilderX 与基础库处于较新版本,并以各平台真机能力为准。事件相关 API 在 Web、微信小程序、Android、iOS、HarmonyOS 五个平台的一致性支持版本均为 5.25(见下文各 API 的兼容性表)。

uni.onAppRoute(callback)

监听应用路由成功后的事件。

兼容性:Web 5.25 / 微信小程序 5.25 / Android 5.25 / iOS 5.25 / HarmonyOS 5.25。

参数

| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | callback | (event: AppRouteEvent) => void | 是 | 应用路由事件回调 |

AppRouteEvent 的属性值

| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | path | string | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由页面路径,不包含开头的斜杠 | | query | UTSJSONObject | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由页面参数 | | openType | string | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 应用路由类型 | | notFound | boolean | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由页面是否不存在。支付宝小程序不提供该信息,固定为 false | | timeStamp | number | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 事件触发时的时间戳 | | routeEventId | string | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由事件唯一标识 | | page | IAnyObject | 否 | 微信小程序: 4.41 | 当前打开页面的相关配置 | | pipMode | string | 否 | 微信小程序: 4.41 | 可选值:'min'(视频页面缩小为小窗)、'max'(视频小窗还原为页面) | | renderer | string | 否 | 微信小程序: 4.41 | 渲染引擎。可选值:'webview''skyline''xr-frame'| | webviewId | number | 否 | 微信小程序: 4.41 | 当前页面 id |

其中pagepipModerendererwebviewId为微信小程序特有的扩展字段,其他平台不会提供,跨平台代码中不要依赖。

使用说明

onAppRoute只描述最终实际生效的路由。一次路由发生重写时,被替换的中间目标不会触发onAppRoute,只有最终成功进入的页面触发一次。

监听器抛出的异常不会中断底层路由流程,但应在监听器内部妥善处理业务异常。

const appRouteCallback = (event : AppRouteEvent) => { console.log(`路由完成:${event.openType} ${event.path}`) console.log(`路由参数:${JSON.stringify(event.query)}`) } uni.onAppRoute(appRouteCallback) // 不再监听时,传入注册时的同一个函数对象。 uni.offAppRoute(appRouteCallback)

uni.offAppRoute(callback?)

取消监听应用路由事件。不传 callback 时移除全部监听器。

兼容性:Web 5.25 / 微信小程序 5.25 / Android 5.25 / iOS 5.25 / HarmonyOS 5.25。

参数callback类型为(event: AppRouteEvent) => void,可选。事件属性值与onAppRoute相同。

移除监听器

传入监听函数时,只移除同一个函数对象对应的监听器;不传参数或传入null时,移除通过onAppRoute注册的全部监听器。

const callback1 = (event : AppRouteEvent) => { console.log(event.path) } const callback2 = (event : AppRouteEvent) => { console.log(event.openType) } uni.onAppRoute(callback1) uni.onAppRoute(callback2) // 只移除 callback1。 uni.offAppRoute(callback1) // 移除全部 onAppRoute 监听器。 uni.offAppRoute()

onAppRouteonBeforeAppRoute的监听器相互独立,清空其中一类不会影响另一类。

uni.onBeforeAppRoute(callback)

监听应用路由发生前的事件。

兼容性:Web 5.25 / 微信小程序 5.25 / Android 5.25 / iOS 5.25 / HarmonyOS 5.25。

参数

| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | callback | (event: BeforeAppRouteEvent) => void | 是 | 应用路由前置事件回调 |

BeforeAppRouteEvent 的属性值

| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | path | string | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由页面路径,不包含开头的斜杠 | | query | UTSJSONObject | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由页面参数 | | openType | string | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 应用路由类型 | | notFound | boolean | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由页面是否不存在。支付宝小程序不提供该信息,固定为 false | | routeEventId | string | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 路由事件唯一标识 | | page | IAnyObject | 否 | 微信小程序: 4.41 | 当前打开页面的相关配置 | | pipMode | string | 否 | 微信小程序: 4.41 | 可选值:'min''max'| | renderer | string | 否 | 微信小程序: 4.41 | 渲染引擎。可选值:'webview''skyline''xr-frame'| | webviewId | number | 否 | 微信小程序: 4.41 | 当前页面 id |

注意与AppRouteEvent的区别:BeforeAppRouteEvent不包含timeStamp字段。

使用说明

onBeforeAppRoute回调同步执行。可以根据目标页面、路由参数和路由类型记录信息,也可以在该回调中同步调用rewriteRoute

const beforeAppRouteCallback = (event : BeforeAppRouteEvent) => { console.log(`准备路由:${event.openType} ${event.path}`) console.log(`路由参数:${JSON.stringify(event.query)}`) } // 如需处理 appLaunch,应在 App.uvue 的 onLaunch 中尽早注册。 onLaunch(() => { uni.onBeforeAppRoute(beforeAppRouteCallback) })

同一个routeEventId对应的onBeforeAppRoute最多触发一次。重写后的目标会作为新一轮路由再次触发onBeforeAppRoute,并使用新的routeEventId

uni.offBeforeAppRoute(callback?)

取消监听应用路由前置事件。不传 callback 时移除全部监听器。

兼容性:Web 5.25 / 微信小程序 5.25 / Android 5.25 / iOS 5.25 / HarmonyOS 5.25。

参数callback类型为(event: BeforeAppRouteEvent) => void,可选。事件属性值与onBeforeAppRoute相同。

移除监听器

offBeforeAppRoute的移除规则与offAppRoute相同:传入注册时的同一个函数对象,只移除该监听器;不传参数或传入null,移除全部前置路由监听器。

const beforeAppRouteCallback = (event : BeforeAppRouteEvent) => { console.log(event.path) } uni.onBeforeAppRoute(beforeAppRouteCallback) uni.offBeforeAppRoute(beforeAppRouteCallback) // 移除全部 onBeforeAppRoute 监听器。 uni.offBeforeAppRoute()

uni.rewriteRoute(options)

在应用路由前置事件回调中重写当前路由。

兼容性:Web 5.25 / 微信小程序 5.25 / Android 5.25 / iOS 5.25 / HarmonyOS 5.25。

参数

| 名称 | 类型 | 必填 | | :- | :- | :- | | options |RewriteRouteOptions| 是 |

options 的属性描述

| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | url | string (string.PageURIString) | 是 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 重写后的页面路径 | | preserveQuery | boolean | 否 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 是否保留原路由参数,默认 false | | success | (result: RewriteRouteSuccess) => void | 否 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 接口调用成功的回调函数 | | fail | (result: RewriteRouteFail) => void | 否 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 接口调用失败的回调函数 | | complete | (result: RewriteRouteComplete) => void | 否 | Web: 5.25; 微信小程序: 5.25; Android: 5.25; iOS: 5.25; HarmonyOS: 5.25 | 接口调用结束的回调函数 |

RewriteRouteSuccess 的属性值

| 名称 | 类型 | 必备 | | :- | :- | :- | | errMsg | string | 是 |

RewriteRouteFail 的属性值

| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errCode | number | 是 | 路由错误码
- 4: 框架内部异常 | | errSubject | string | 是 | 统一错误主题(模块)名称 | | data | any | 否 | 错误信息中包含的数据 | | cause | Error | 否 | 源错误信息,可以包含多个错误,详见 SourceError | | errMsg | string | 是 | 错误信息 |

RewriteRouteComplete 的属性值

| 名称 | 类型 | 必备 | | :- | :- | :- | | errMsg | string | 是 |

路由重写规则

rewriteRoute用于重写当前正在处理的路由事件,且不支持 Promise 风格调用。调用时需遵守以下规则:

  • 只能在onBeforeAppRoute回调中同步调用。在回调外调用,或在回调中的异步任务内调用,都会失败。
  • 同一个routeEventId只允许成功重写一次。存在多个前置监听器时,首次重写成功后,同一轮的后续重写调用会失败。
  • 重写只改变目标路径和参数,不改变原路由的openType
  • navigateBack路由不允许重写。
  • 重写后的目标必须符合原路由类型的约束。例如,switchTab只能重写到 tabBar 页面,navigateTo不能重写到 tabBar 页面。
  • 重写目标会重新执行路径、页面存在性和路由类型校验。校验失败时保留当前轮的原目标,并通过fail返回失败信息。
  • 框架会限制连续重写次数以避免循环重写,超过限制时本次重写失败。微信小程序直接使用宿主的重写能力,遵循微信小程序的限制。

preserveQuery默认为false

  • false时,使用url中携带的参数。
  • true时,完整保留当前路由事件的参数,并丢弃url中携带的参数。

例如,当前目标参数为a=1,重写地址为/pages/new/new?b=2preserveQueryfalse时最终参数为b=2;为true时最终参数为a=1

const beforeAppRouteCallback = (event : BeforeAppRouteEvent) => { if ( event.openType == 'navigateTo' && event.path == 'pages/old/old' ) { uni.rewriteRoute({ url: '/pages/new/new?from=rewrite', preserveQuery: false, success: (result) => { console.log(result.errMsg) }, fail: (error) => { console.error(error.errMsg) }, complete: (result) => { console.log(result.errMsg) } }) } } uni.onBeforeAppRoute(beforeAppRouteCallback)

回调语义:success表示本次重写请求已被接受;fail表示本次重写被拒绝;无论成功或失败都会调用complete

连续重写

重写后的目标会作为新的路由事件重新触发onBeforeAppRoute。因此,"同一个路由事件只允许成功重写一次"不表示一次用户跳转只能重写一次。

A -> onBeforeAppRoute(routeEventId=1) -> 重写到 B B -> onBeforeAppRoute(routeEventId=2) -> 重写到 C C -> onBeforeAppRoute(routeEventId=3) -> 执行路由 C -> onAppRoute(routeEventId=3)

业务代码应避免不同重写规则之间形成循环(框架虽然会限制连续重写次数,但循环重写仍会白白消耗一次用户跳转并产生失败日志)。

完整示例:监听、记录与重写一次跳转

下面是一个完整的可运行页面,演示了开始/停止监听、记录onBeforeAppRouteonAppRoute事件、以及将下一次navigateTo重写到目标页并附加from=rewrite参数的全过程:

<template> <view class="route-page uni-theme-root"> <page-head title="应用路由事件"></page-head> <view class="uni-padding-wrap"> <view class="uni-list-cell-padding status-box"> <text class="uni-title-text">监听状态</text> <text class="status-text">{{ data.isListening ? '监听中' : '已停止' }}</text> <text class="status-text">onBeforeAppRoute:{{ data.beforeAppRouteCount }} 次</text> <text class="status-text">onAppRoute:{{ data.appRouteCount }} 次</text> </view> <view class="uni-btn-v uni-common-mt"> <button type="primary" @click="navigateToTarget">普通跳转</button> <button @click="navigateToRewriteTarget">重写下一次跳转</button> <button @click="startListen">开始监听</button> <button @click="stopListen">停止监听</button> <button @click="clearRecords">清空记录</button> </view> <view class="event-box uni-common-mt"> <text class="uni-title-text">onBeforeAppRoute 记录</text> <text v-if="data.beforeAppRouteEvents.length == 0" class="event-text">暂无记录</text> <view v-for="(event, index) in data.beforeAppRouteEvents" :key="index" class="event-item"> <text class="event-index">#{{ index + 1 }}</text> <text class="event-text">{{ event }}</text> </view> </view> <view class="event-box uni-common-mt"> <text class="uni-title-text">onAppRoute 记录</text> <text v-if="data.appRouteEvents.length == 0" class="event-text">暂无记录</text> <view v-for="(event, index) in data.appRouteEvents" :key="index" class="event-item"> <text class="event-index">#{{ index + 1 }}</text> <text class="event-text">{{ event }}</text> </view> </view> <view class="event-box uni-common-mt"> <text class="uni-title-text">最近一次 rewriteRoute 结果</text> <text class="event-text">{{ data.rewriteRouteResult }}</text> </view> </view> </view> </template> <script setup lang="uts"> const TARGET_PATH = 'pages/API/app-route/app-route-target' const TARGET_URL = `/${TARGET_PATH}` type DataType = { isListening : boolean beforeAppRouteCount : number appRouteCount : number beforeAppRouteEvents : string[] appRouteEvents : string[] lastNavigateToBeforePath : string lastNavigateToAppRoutePath : string rewriteRouteResult : string } const data = reactive({ isListening: false, beforeAppRouteCount: 0, appRouteCount: 0, beforeAppRouteEvents: [] as string[], appRouteEvents: [] as string[], lastNavigateToBeforePath: '', lastNavigateToAppRoutePath: '', rewriteRouteResult: '' } as DataType) let rewriteNextRoute = false const appRouteCallback = (event : AppRouteEvent) => { data.appRouteCount++ data.appRouteEvents.push(JSON.stringify(event)) if (event.openType == 'navigateTo') { data.lastNavigateToAppRoutePath = event.path } } const beforeAppRouteCallback = (event : BeforeAppRouteEvent) => { data.beforeAppRouteCount++ data.beforeAppRouteEvents.push(JSON.stringify(event)) if (event.openType == 'navigateTo') { data.lastNavigateToBeforePath = event.path } if (rewriteNextRoute && event.openType == 'navigateTo' && event.path == TARGET_PATH) { rewriteNextRoute = false uni.rewriteRoute({ url: `${TARGET_URL}?from=rewrite`, success: (result) => { data.rewriteRouteResult = result.errMsg }, fail: (error) => { data.rewriteRouteResult = error.errMsg } }) } } const startListen = () => { if (data.isListening) { return } uni.onAppRoute(appRouteCallback) uni.onBeforeAppRoute(beforeAppRouteCallback) data.isListening = true } const stopListen = () => { if (!data.isListening) { return } uni.offAppRoute(appRouteCallback) uni.offBeforeAppRoute(beforeAppRouteCallback) data.isListening = false rewriteNextRoute = false } const clearRecords = () => { data.beforeAppRouteCount = 0 data.appRouteCount = 0 data.beforeAppRouteEvents.length = 0 data.appRouteEvents.length = 0 data.lastNavigateToBeforePath = '' data.lastNavigateToAppRoutePath = '' data.rewriteRouteResult = '' } const navigateToTarget = () => { rewriteNextRoute = false uni.navigateTo({ url: `${TARGET_URL}?from=normal` }) } const enableRewriteNextRoute = () => { rewriteNextRoute = true } const navigateToRewriteTarget = () => { enableRewriteNextRoute() uni.navigateTo({ url: `${TARGET_URL}?from=source`, fail: () => { rewriteNextRoute = false } }) } onLoad(() => { startListen() }) onUnload(() => { stopListen() }) defineExpose({ data, startListen, stopListen, clearRecords, enableRewriteNextRoute, navigateToTarget, navigateToRewriteTarget }) </script> <style> .status-box, .event-box { padding: 12px; background-color: var(--list-background-color, #ffffff); } .status-text, .event-text { margin-top: 8px; color: var(--text-color, #333333); } .event-text { width: 100%; } .event-item { padding-top: 8px; padding-bottom: 8px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: var(--border-color, #eeeeee); } .event-index { color: var(--active-color, #999999); } </style>

示例中的关键设计点:

  • startListen/stopListen成对注册与注销,且传入的是同一个函数对象,符合offAppRouteoffBeforeAppRoute的移除规则;
  • 重写动作只对"下一次navigateTo到目标路径"生效,rewriteNextRoute标志在成功重写后立即复位,避免影响后续路由;
  • onLoad中开始监听、onUnload中停止监听,页面销毁时不会残留监听器。

通用类型

GeneralCallbackResult

| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errMsg | string | 是 | 错误信息 |

最佳实践小结

  1. 按"一次路由"划分职责:全局状态重置、埋点上报、登录态拦截等横切逻辑放进路由事件回调;页面自身的数据加载、UI 初始化放到页面生命周期(onLoadonShow等)。
  2. 尽早注册以覆盖 appLaunch:如需监听或重写应用启动路由,应在App.uvueonLaunch中(或更早)注册onBeforeAppRoute,因为监听器注册前的事件不会补发。
  3. 同步调用 rewriteRoute:只能在onBeforeAppRoute同步回调中调用,异步任务内调用会失败;重写不改变openType,且navigateBack不可重写。
  4. 重写目标需符合路由类型约束switchTab只能重写到 tabBar 页面,navigateTo不能重写到 tabBar 页面;重写目标会重新走路径、存在性与类型校验。
  5. 成对注册与注销:注销时必须传入注册时的同一个函数对象;onAppRouteonBeforeAppRoute的监听器相互独立,清空互不影响。
  6. 关注平台差异:微信小程序rewriteRoute要求基础库 3.8.0+ 且模拟器不支持;支付宝小程序notFound恒为false且不支持rewriteRoute,跨端代码只依赖公共字段。
  7. 防止循环重写:连续重写会产生新的routeEventId并再次触发前置事件,业务规则之间应保证重写关系无环。

参考文档

  • 应用路由事件官方文档:本指南的原始依据,包含全部 API 定义、兼容性与示例。
  • 页面生命周期:路由事件与onLoadonShow等页面生命周期的时序对照。
  • dialogPage:了解 dialogPage 为何不参与应用路由事件。
  • UTSJSONObject:事件参数query的类型说明。
  • 错误规范:RewriteRouteFail.causeError的结构定义。
  • release-note-alpha.md:uni.onAppRouteuni.onBeforeAppRouteuni.rewriteRoute的版本引入记录。

【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询