uni-router v1.1.1发布:守卫超时保护+路由监听 v1.1.0 新增守卫超时保护、路由变化监听等能力v1.1.1 修复 back() 守卫执行、状态同步和兼容性问题v1.1.0从能用到好用v1.0.0 建立了 uni-router 的核心能力——导航、守卫、元信息、类型提示。但在实际项目中几个高频问题反复出现守卫中写了异步请求忘了调next()导航永远挂起想监听路由变化做埋点只能在每个afterEach里手动处理物理返回键导致路由状态不同步onRouteChange无法感知RouterLink 导航失败时没有反馈用户无感知v1.1.0 针对这些场景逐一解决。守卫超时保护防止导航永久挂起这是 v1.1.0 最重要的新增能力。在实际项目中守卫函数经常包含异步逻辑router.beforeEach(async(to,from,next){// 网络请求可能超时、可能失败consthasPermissionawaitcheckPermission(to.meta)if(hasPermission)next()elsenext({name:login})})如果checkPermission永远不返回网络挂起、逻辑遗漏next()永远不会被调用导航就永远挂起——页面既不跳转也不报错用户看到的是点了没反应。v1.1.0 新增guardTimeout配置项constroutercreateRouter({routes,guardTimeout:10000// 10 秒超时默认值})当守卫在指定时间内既未调用next()也未返回 rejected Promise 时框架自动中止导航并输出警告[uni-router] Navigation guard timed out after 10000ms. Navigation aborted.设为0可禁用超时保护不推荐。实现原理框架为每个守卫创建超时计时器与守卫的 Promise 使用Promise.race竞争privaterunGuardWithTimeout(guard,to,from):PromiseGuardResult{constguardPromiserunGuard(guard,to,from)if(!this._guardTimeout)returnguardPromiseconsttimeoutPromisenewPromiseGuardResult(resolve{setTimeout((){warn(Navigation guard timed out after${this._guardTimeout}ms. Navigation aborted.)resolve({type:abort,code:NAVIGATION_CANCELLED})},this._guardTimeout)})returnPromise.race([guardPromise,timeoutPromise])}超时后守卫仍可能继续执行并调用next()但此时导航已被中止next()调用会被静默忽略通过resolved标志位保证next()只生效一次。路由变化监听onRouteChangev1.0.0 提供了afterEach后置钩子但它只在路由器主动发起的导航完成时触发。当路由状态通过syncRoute()同步时如物理返回键afterEach不会触发。v1.1.0 新增onRouteChange()统一监听所有路由变化router.onRouteChange((to,from){// 导航完成和状态同步都会触发analytics.track(page_view,{from:from.path,to:to.path})})与afterEach的区别特性afterEachonRouteChange路由器导航完成触发触发syncRoute 同步不触发触发可移除返回移除函数返回移除函数用途导航后置逻辑路由状态变化订阅设计考量afterEach是导航流程的一部分语义上导航完成后执行onRouteChange是状态订阅语义上路由状态变了就通知我。两者职责不同不应合并。路由状态同步标记RouteLocation._syncedonRouteChange统一了两种路由变化的监听但有时需要区分变化来源——比如埋点时导航触发的页面浏览需要记录但状态同步触发的可能是重复记录。v1.1.0 在RouteLocation上新增_synced标记router.onRouteChange((to,from){if(!to._synced){// 真正的导航记录页面浏览analytics.track(page_view,{path:to.path})}// 状态同步如物理返回键仅更新 UI 状态updateActiveTab(to.path)})_synced为true表示该路由变化由syncRoute()/syncCurrentRoute()触发不是一次完整的导航未经过前置守卫。RouterLink 错误事件v1.0.0 的 RouterLink 组件在导航失败时静默吞掉错误开发者无法在模板层面处理失败场景。v1.1.0 新增error事件mxuni-router to/pages/protected/index erroronNavError view需要登录的页面/view /mxuni-routerfunctiononNavError(error:NavigationFailure){if(error.codeNAVIGATION_ABORTED){uni.showToast({title:导航被拦截,icon:none})}}其他优化fullPath 确定性—buildFullPath对 query 参数键排序确保{ a: 1, b: 2 }和{ b: 2, a: 1 }生成一致的fullPath避免因参数顺序不同导致重复导航误判install 类型修正—install(app)参数类型从unknown改为AppIDE 智能提示更准确uni API 拦截增强— 拦截器逻辑优化提升拦截稳定性守卫执行增强— 守卫链执行逻辑优化支持超时保护与异常处理v1.1.1关键 Bug 修复v1.1.1 修复了 v1.1.0 中发现的 4 个问题其中 2 个影响核心功能。back() 未触发 afterEach问题router.back()导航完成后afterEach后置钩子未执行。如果依赖afterEach做页面标题设置或埋点返回操作会漏掉。原因back()方法在调用goBack()后只执行了syncCurrentRoute()遗漏了runAfterGuards()。修复asyncback(delta1){// ...守卫执行...try{awaitgoBack(delta)this.syncCurrentRoute(from)this.guardManager.runAfterGuards(to,from)// 补充触发 afterEach}catch(error){// ...}}back() 守卫模式错误问题back()导航的守卫模式使用了push导致守卫链无法区分前进导航和返回导航。修复handleGuardResult和executeNavigation方法签名新增back模式back()调用时传入back。syncRoute() 忽略 query 变化问题syncRoute()只比较路径不比较查询参数。当页面 query 变化但路径不变时如/pages/detail?id1→/pages/detail?id2路由状态不会更新。修复syncRoute():void{constfromthis.routeState.getCurrentRoute()constcurrentPathgetCurrentPagePath()constcurrentQuerygetCurrentPageQuery()// 同时比较路径和查询参数if(currentPathfrom.paththis.isSameQuery(currentQuery,from.query))returnthis.syncCurrentRoute(from)}app.onUnmount 兼容性问题install中直接调用app.onUnmount()但这是 Vue 3.5 新增 APIuni-app 的 app 实例不支持导致运行时报错app.onUnmount is not a function。修复添加防御性检查if(typeofapp.onUnmountfunction){app.onUnmount(()removeInterceptors())}在 uni-app 中应用不会真正卸载拦截器无需清理因此跳过此调用不影响功能。升级指南从 v1.1.0 升级到 v1.1.1 无需任何代码修改直接更新依赖即可pnpmaddmeng-xi/uni-router1.1.1uni_modules 用户将mxuni-router目录替换为新版本即可。版本对比能力v1.0.0v1.1.0v1.1.1路由导航✅✅✅路由守卫✅✅✅命名路由✅✅✅路由元信息✅✅✅TypeScript 类型提示✅✅✅uni API 拦截✅✅增强✅守卫超时保护❌✅✅路由变化监听❌✅✅RouterLink error❌✅✅back() afterEach❌❌缺失✅修复syncRoute() query❌❌缺失✅修复app.onUnmount 兼容❌❌报错✅修复写在最后v1.1.x 系列的核心主题是健壮性——守卫超时保护防止导航挂起onRouteChange弥补状态同步的监听缺口Bug 修复确保核心流程正确执行。如果你已经在使用 v1.0.0 或 v1.1.0强烈建议升级到 v1.1.1。反馈和贡献请前往 GitHub Issues。