0.8.2 新增 backFallback 配置,无 tabbar 页返回无忧

v0.8.2 为 PATCH 版本(0.8.1 → 0.8.2),新增 RouterOptions.backFallback 配置项,把 0.8.1 引入的「返回栈底兜底」能力扩展到无 tabBar 页的工程 。无破坏性变更 ;未配置 backFallback 时行为与 0.8.1 完全一致,升级无需改动代码。

一、背景:0.8.1 兜底机制与它的目标缺口

v0.8.1 修复了「H5 刷新 / 冷启动直连非首页后返回无效」,核心机制是返回栈底兜底 :back() 遇到页面栈不足(栈长 < 2 或 delta >= 栈长)时,自动 relaunch 到入口页而非 reject CANCELLED。

「入口页」的解析方式是自动推断 ------取路由表中首个声明 meta.isTab: true 的路由。这在有 tabBar 的工程里工作良好,但存在一个缺口:

没有 tabBar 页的工程推断不出兜底目标。 典型形态是 navigationStyle: custom 的自绘导航应用(组件库演示站、全屏 H5 活动页等),页面栈长这样:

  • 路由表中没有任何 meta.isTab: true 路由 → 推断结果为 null;
  • back() 退回 0.8.1 之前的行为:reject CANCELLED;
  • 若调用方(自定义导航栏组件的返回按钮)没有 .catch,H5 控制台出现 Uncaught (in promise)------0.8.1 之前这类工程的问题原样回来,还多了一个报错堆栈。

二、真实案例复盘:unix-ui 组件演示 playground

该工程是典型的无 tabBar 形态:全部页面 navigationStyle: custom,导航由 demo-navbar 组件自绘,返回按钮调用 router.back(1);路由表(router.config.uts)10 条路由均无 isTab;路由器未注册 InterceptorPlugin。

故障链(0.8.1 下复现):

scss 复制代码
H5 刷新子页 /pages-sub/button/button(页面栈 = 1)
  → 点击 demo-navbar 返回箭头
  → router.back(1)
  → 栈深不足 → backWithStackFallback()
  → findFirstTabRoutePath() = null(无 isTab 路由)
  → reject CANCELLED(NavigationFailure)
  → demo-navbar 未捕获 → Uncaught (in promise) ,页面原地不动

v0.8.2 配置 backFallback: { name: 'home' } 后实测:同场景点击返回 → 正确回首页(pages/index/index),控制台输出警告「按 backFallback 配置兜底重载」,无任何未捕获异常。

三、新增:backFallback 配置项

显式声明兜底目标(RouteLocationRaw,支持命名路由对象或路径字符串),优先级高于 isTab 自动推断:

ts 复制代码
import { createRouter } from '@meng-xi/unix-router'

export const router = createRouter({
	routes,
	strict: true,
	// 无 tabBar 工程:栈深不足时(H5 刷新后点返回)回首页
	backFallback: { name: 'home' }
	// 等价写法:backFallback: '/pages/index/index'
})

兜底目标解析优先级:

objectivec 复制代码
backFallback 显式配置 → 首个 meta.isTab 路由 → 维持 reject CANCELLED

配套调整:拦截器根路径兜底联动

H5 框架导航栏返回箭头在栈深 = 1 时调用的是 uni.reLaunch({ url: '/' })(uni-h5 内部 onPageHeadBackButton)。InterceptorPlugin 对根路径 reLaunch 的转交逻辑同步调整:

  • 路由表有 isTab 路由 → 直接 relaunch 到首个 isTab 路由(与 0.8.1 一致);
  • 路由表无 isTab 路由 → 委托 back(1),由 backWithStackFallback 按 backFallback 配置兜底(未配置则维持 CANCELLED)。

各配置组合下的返回行为矩阵

工程配置 H5 框架导航栏返回箭头¹ 自绘导航 router.back(1)
有 isTab 路由 + InterceptorPlugin relaunch 首个 isTab 路由 isTab 推断兜底
有 isTab 路由、无拦截器 框架原生处理(不经路由器) isTab 推断兜底
无 isTab + backFallback + InterceptorPlugin 委托 back(1) → 兜底到配置页 兜底到配置页
无 isTab + backFallback、无拦截器 框架原生处理(不经路由器) 兜底到配置页
无 isTab、未配置 backFallback 框架原生处理 / CANCELLED reject CANCELLED(未捕获时报错)

¹ H5 框架导航栏返回箭头仅在页面未使用 navigationStyle: custom 时存在。

四、设计说明:为什么默认不「猜」兜底目标

一个自然的疑问:无 isTab 路由时为什么不自动取「路由表首条路由」兜底,而要求显式配置?

因为首条路由不可靠 。以本仓库 playground 为例,routes.gen.uts 由 routeGen 按 localeCompare 排序生成,首条是分包页 pages-sub/checkout/checkout------且声明了 requireAuth: true。若自动兜底到它,会被守卫重定向到登录页,产生比「返回无效」更困惑的行为。入口页在不同工程里可能是首页、引导页或落地页,库无法可靠猜测,显式配置是唯一不产生意外的方式。

这也决定了 backFallback 的定位:有 tabBar 工程零配置不受影响;无 tabBar 工程补一行配置即可获得与 0.8.1 等价的兜底能力。

五、运行验证

验证项 场景 结果
配置优先级 有 tabBar 工程临时配置 backFallback: { name: 'mine' },冷启动详情页后触发 uni.navigateBack ✅ 落地「我的」页而非首页(配置胜出),警告「按 backFallback 配置兜底重载」正常输出
无 tabBar 工程实测 unix-ui playground:冷启动 /pages-sub/button/button → 点自绘导航返回箭头 ✅ 回首页 pages/index/index,无 Uncaught (in promise)
回归 unix-router playground(有 tab、未配置)冷启动详情页 → 点返回箭头 ✅ 行为与 0.8.1 一致(relaunch 首个 isTab 路由)

以上均为浏览器实测(CDP),验证过程含守卫链日志核对(beforeResolve / afterEach 正常触发)。

六、版本说明

PATCH 版本(0.8.1 → 0.8.2),仅新增一个可选配置项,无 API 移除、无行为变更、无破坏性变更。

版本兼容性

功能 0.8.1 0.8.2
核心 API(push / replace / relaunch / back / 守卫 / 插件) ✅ ✅(不变)
back() 栈深不足(路由表有 isTab 路由、未配置 backFallback) ✅ 兜底入口页 ✅(不变)
back() 栈深不足(路由表无 isTab 路由、未配置 backFallback) ❌ reject CANCELLED ❌ reject CANCELLED(不变)
back() 栈深不足(配置 backFallback) ---(无此选项) ✅ 兜底 relaunch 到配置页

七、升级指南

0.8.1 → 0.8.2 无需改动代码:

bash 复制代码
pnpm add @meng-xi/unix-router@0.8.2

建议 :无 tabBar 页的工程(自绘导航 / 全屏应用)补一行 backFallback 配置,使 H5 刷新、返回键、deeplink 冷启动等栈底场景的返回行为可控;有 tabBar 工程无需任何调整。

八、相关链接

欢迎反馈与共建:GitHub

相关推荐
淡漠的蓝精灵1 小时前
web.py:一个简单到极致的 Python Web 框架
开发语言·前端·python·其他
开开心心就好2 小时前
竖式除法出题工具,整除余数混合模式
运维·服务器·前端·javascript·ocr·perl·1024程序员节
起个名字费劲死了2 小时前
Halcon学习一:骰子识别
前端·python·学习
大江东去浪淘尽千古风流人物2 小时前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
其实防守也摸鱼2 小时前
Chrome 扩展安全攻防实录:从攻击面到防御实践
开发语言·前端·网络·chrome·安全·web安全·php
web打印社区2 小时前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket
李剑一2 小时前
为什么几乎所有的知名开源项目都是外国人写的?
前端·ai编程·deepseek
小郎君6582 小时前
(一)为什么表单需要第三种状态:disabled、readonly 与纯文本展示
前端·vue.js
计算机魔术师2 小时前
1.4万亿没人接,OpenAI自己砍了1500亿
前端