News
首页  -  资讯  - 
v2.6.0 新增全局返回守卫与 iOS 侧滑拦截,补齐跨端路由拦截能力
v2.6.0 新增全局返回守卫与 iOS 侧滑拦截,补齐跨端路由拦截能力 v2.6.0 补全返回拦截能力。新增 router.onBeforeBack() 全局返回守卫,覆盖 App 物理返回键 / 顶部导航栏返回 / uni.navigateBack 、H5 浏览器后退按钮 / 后退手势;新增 app.setSideSlipGesture 控制 iOS 侧滑返回手势,使侧滑返回也能走守卫链。配套...

v2.6.0 新增全局返回守卫与 iOS 侧滑拦截,补齐跨端路由拦截能力 v2.6.0 补全返回拦截能力。新增 router.onBeforeBack() 全局返回守卫,覆盖 App 物理返回键 / 顶部导航栏返回 / uni.navigateBack 、H5 浏览器后退按钮 / 后退手势;新增 app.setSideSlipGesture 控制 iOS 侧滑返回手势,使侧滑返回也能走守卫链。配套新增 getPlatform() 统一系统判断利器,替换散落的 typeof window / typeof plus 特殊判断。 前言 此前返回操作无法被路由守卫拦截: App 端 :物理返回键、顶部导航栏返回按钮、外部 uni.navigateBack 均由系统直接处理, beforeEach 等守卫不执行 H5 端 :浏览器后退按钮 / 后退手势由浏览器接管,同样绕过守卫 iOS 侧滑返回 :原生手势直接返回,不触发 onBackPress onBeforeRouteLeave (v2.2.0)只能拦截经过路由器的导航( push / replace / back / relaunch ),对上述原生返回入口无效 v2.6.0 通过全局 mixin 接入 onBackPress (App)+ popstate 事件(H5),实现返回守卫;配合 app.setSideSlipGesture 解决 iOS 侧滑绕过问题。方案借鉴 uni-simple-router 的全局 mixin 思路,无需 UTS 原生插件,保持跨端一致性。 一、能力总览 功能 说明 router.onBeforeBack() 全局返回守卫,返回操作触发时执行; false 阻止、 true / undefined 放行,适配异步 app.setSideSlipGesture App 平台 iOS 侧滑返回手势控制, 'none' 禁用(走守卫链)/ 'close' 开启原生 getPlatform() 统一平台判断工具(基于 uni.getSystemInfoSync() ,带缓存),返回 PlatformInfo 平台判断统一 InterceptorPlugin 的 isWebPlatform() 改用 getPlatform().isH5 二、onBeforeBack - 全局返回守卫 1. API 设计 export type BackGuardReturn = boolean | void | Promise < boolean | void > export type BackGuard = ( to: RouteLocation, from : RouteLocation ) => BackGuardReturn // Router 接口新增 onBeforeBack ( guard : BackGuard ): () => void to - 返回目标页面(上一页) from - 当前正要离开的页面 返回 false 阻止返回; true / undefined 放行;支持异步(Promise),不受 uni-app onBackPress 同步返回限制 返回值为移除函数,可动态注册/移除一次性守卫 2. 守卫链执行顺序 返回操作触发 → onBeforeBack(任一返回 false 即拦截,NAVIGATION_ABORTED) → beforeEach(支持中止/重定向) → beforeResolve → 全部放行后执行 uni.navigateBack / 浏览器后退 → after Each 返回守卫放行后复用 beforeEach → beforeResolve 完整链路,中止 / 重定向行为与完整导航一致。 3. App 端接入(onBackPress) 通过全局 mixin 向每个页面注入 onBackPress ,覆盖物理返回键 / 顶部导航栏返回 / navigateBack : app. mixin ({ onShow ( ) { router. syncRoute () router. applySideSlipGesture () }, onBackPress ( ) { return router. handleBackPress () } }) handleBackPress() 处理逻辑: 仅 App 平台拦截( getPlatform().isApp ),H5 / 小程序保持默认返回行为 递归保护 :路由器发起的返回( router.back() / 守卫放行后的手动返回)会再次触发 onBackPress ,通过 backGuardRunning 标记放行,避免守卫重复执行与死循环 根页面 (页面栈 < 2)放行默认行为(如 Android 物理键退出应用) 其余情况返回 true 阻止默认返回,异步执行守卫链( onBackPress 必须同步返回,守卫链以 fire-and-forget 方式运行),放行后手动 uni.navigateBack 4. H5 端接入(popstate) 通过 popstate 事件接入浏览器后退按钮 / 后退手势。popstate 触发时浏览器已完成后退,采用「撤销后退 → 守卫放行后重新后退」策略: 1. 记录当前页 URL(h5BackUrl),popstate 后 URL 已变化说明发生了后退 2. history.go(1) 恢复当前页(触发二次 popstate,命中「回到当前页」分支放行) 3. 同步捕获 to/from 执行返回守卫链 4. 守卫放行后重新后退(再次触发 popstate,由 backGuardRunning 放行) 5. 平台支持矩阵 返回入口 平台 可拦截 物理返回键 App(Android) ✅ 顶部导航栏返回按钮 App ✅ uni.navigateBack App ✅ 浏览器后退按钮 / 后退手势 H5 ✅ iOS 侧滑返回 App(iOS) 默认绕过;配置 app.setSideSlipGesture('none') 后 ✅ 小程序原生返回 小程序 ❌(无法拦截) 三、iOS 侧滑返回手势控制(app.setSideSlipGesture) 1. API 设计 export type SideSlipGesture = 'none' | 'close' export interface AppRouterOptions { /** 在页面 onShow 时调用,返回 'none' 禁用手势 / 'close' 开启原生手势 */ setSideSlipGesture?: ( to: RouteLocation ) => SideSlipGesture } export interface RouterOptions { // ... /** App 平台专属配置(侧滑返回手势等) */ app?: AppRouterOptions } 2. 实现细节 由全局 mixin 在页面 onShow 时调用 applySideSlipGesture() 仅 iOS 平台生效( getPlatform().isIOS ),Android 使用物理返回键,由 onBackPress 拦截 通过 plus.webview.currentWebview()?.setStyle({ popGesture: value }) 动态修改手势 未配置 app.setSideSlipGesture 时不干预手势,保持 uni-app 默认行为 3. 用法示例 const router = createRouter ({ routes, app : { // 'none' 禁用侧滑返回(走守卫链,onBeforeBack 生效) // 'close' 开启原生侧滑返回(保留手势,侧滑绕过守卫) setSideSlipGesture ( to ) { return to. meta . requireAuth ? 'none' : 'close' } } }) 四、getPlatform() - 平台判断工具 1. API 设计 export interface PlatformInfo { isApp : boolean // 是否 App 平台(app / app-harmony) isH5 : boolean // 是否 H5 平台 isMp : boolean // 是否小程序平台(mp-*) isIOS : boolean // 是否 iOS 系统 isAndroid : boolean // 是否 Android 系统 uniPlatform : string // uni-app 平台类型:'app' | 'web' | 'mp-weixin' 等 osName : string // 系统名称:'ios' | 'android' 等 } export function getPlatform ( ): PlatformInfo 2. 兼容性回退 优先使用 uniPlatform / osName (HBuilderX 3.5.3+ 提供) 旧版本不返回 uniPlatform 时,回退到 typeof plus / typeof window 推断 App / H5 uni.getSystemInfoSync() 异常时回退为空,按非 App / 非 H5 处理 首次调用读取并缓存,之后直接返回 3. 新增类型声明 env.d.ts 新增 plus 全局对象(含 webview.currentWebview().setStyle() ) env.d.ts 新增 uni.getSystemInfoSync() 返回类型( uniPlatform / osName / platform ) 五、升级指南 v2.6.0 完全向后兼容,无破坏性变更: 新增 API( onBeforeBack / app.setSideSlipGesture / getPlatform )均为可选能力,未使用不影响现有行为 未配置 app.setSideSlipGesture 时,iOS 侧滑返回保持 uni-app 默认原生行为 返回守卫默认不注册,注册后仅对返回操作生效,不影响 push / replace / relaunch 导航 新增类型导出: BackGuard / BackGuardReturn / AppRouterOptions / SideSlipGesture / PlatformInfo 版本兼容性 功能 v2.5.0 v2.6.0 返回操作拦截(App 物理键/导航栏/navigateBack) 不支持 支持( onBeforeBack ) H5 浏览器后退拦截 不支持 支持( popstate ) iOS 侧滑返回手势控制 不支持 支持( app.setSideSlipGesture ) getPlatform() 平台判断 不支持 支持 完整导航守卫链(beforeEach/beforeResolve/afterEach) 支持 支持 可控重定向 / 冷启动 guardRoute 支持 支持