当前位置: 首页 > news >正文

uni-router v2.1.0 升级:导航守卫全面支持返回值模式

v2.1.0 将导航守卫全面升级为返回值模式(与 Vue Router 4.x 一致),通过 return undefined / return false / return RouteLocationRaw 控制导航行为,无需调用 next() 回调。旧版 next() 回调模式保持兼容,标记为已弃用。

前言

@meng-xi/uni-router 的守卫系统自 v1.0 起一直使用 next() 回调模式控制导航行为。Vue Router 4.x 已全面移除 next() 回调,改为返回值模式,代码更简洁、更符合 async/await 风格。

v2.1.0 将守卫升级为返回值模式,同时保持对旧版 next() 回调的完全兼容,提供平滑迁移路径。


一、问题分析

1. next() 回调容易忘记调用

// v2.0.x — 忘记调用 next() 导致导航挂起
router.beforeEach((to, from, next) => {const valid = await checkToken()if (!valid) {// 忘记调用 next(),导航永久挂起}next()
})

2. 回调嵌套使代码冗长

// v2.0.x — 回调嵌套,可读性差
router.beforeEach((to, from, next) => {if (to.meta.requireAuth) {checkAuth(result => {if (result) {next()} else {next({ name: 'login' })}})} else {next()}
})

3. afterEach 无法区分导航成功/失败

// v2.0.x — afterEach 不知道导航是否成功
router.afterEach((to, from) => {// 无法判断导航是否被守卫中止// 无法判断 uni API 调用是否失败
})

二、新增能力

1. 守卫返回值模式

v2.1.0 引入 Vue Router 4.x 风格的返回值模式,守卫通过返回值控制导航行为:

// v2.1.0 — 返回值模式
router.beforeEach((to, from) => {if (to.meta.requireAuth && !isLoggedIn()) {return { name: 'login' } // 重定向}// 不返回值或 return true 表示放行
})// 异步守卫
router.beforeEach(async (to, from) => {const valid = await checkToken()if (!valid) return false // 中止
})

返回值对照表

返回值 行为
undefined / void / true 放行,继续执行下一个守卫
false 中止导航(NAVIGATION_ABORTED
string(如 '/login' 重定向到路径
RouteLocationRaw(如 { name: 'login' } 重定向到路由位置
Error 对象 取消导航(NAVIGATION_CANCELLED
抛出异常 取消导航(NAVIGATION_CANCELLED

2. 可控重定向的返回值写法

// v2.1.0 — 通过返回值中的 mode 字段指定重定向方式
router.beforeEach((to, from) => {if (to.meta.requireAuth && !isLoggedIn()) {return { location: { name: 'login' }, mode: 'replace' }}if (to.meta.roles && !hasRole(to.meta.roles)) {return { location: { name: 'home' }, mode: 'relaunch' }}
})

3. afterEach 接收 failure 参数

// v2.1.0 — afterEach 可区分导航成功/失败
router.afterEach((to, from, failure) => {if (failure) {console.error('导航失败:', failure.message)return}// 导航成功,设置页面标题if (to.meta.title) {uni.setNavigationBarTitle({ title: to.meta.title as string })}
})

4. NavigationGuardReturn 类型

type NavigationGuardReturn = void | undefined | boolean | RouteLocationRaw | Error | null

三、Bug 修复

1. next() 未调用导致导航挂起

修复前next() 回调模式中,忘记调用 next() 会导致导航永久挂起,需要超时机制兜底,但超时后中止导航而非放行。

修复后:返回值模式中,不返回值等同于 return undefined,自动放行。旧版回调模式保持超时保护。

2. 守卫中止后 afterEach 缺少失败信息

修复前:守卫中止导航时,afterEach 无法获取 NavigationFailure 信息。

修复后:守卫中止、uni API 调用失败等场景,afterEach 的第三个参数 failure 会传入对应的 NavigationFailure 实例。


四、架构设计

守卫模式自动检测

通过函数参数个数 guard.length 自动识别守卫模式:

guard.length >= 3 → (to, from, next) → 回调模式(兼容旧版)
guard.length < 3  → (to, from)       → 返回值模式(推荐)
function runGuard(guard, to, from, timeout) {const useNextCallback = guard.length >= 3if (useNextCallback) {return runGuardWithNext(guard, to, from, timeout)}return runGuardWithReturn(guard, to, from, timeout)
}

返回值模式执行流程

守卫执行├── 返回值 = undefined / true / null → 放行├── 返回值 = false                   → 中止(NAVIGATION_ABORTED)├── 返回值 = RouteLocationRaw        → 重定向├── 返回值 = Error                   → 取消(NAVIGATION_CANCELLED)├── 抛出异常                         → 取消(NAVIGATION_CANCELLED)└── 超时                             → 取消(NAVIGATION_CANCELLED)

混用检测

同时使用 next() 回调和返回值的守卫,会在控制台输出警告:

Navigation guard "guardName" called next() and also returned a value.
Use either next() callback or return value, not both.

五、完整示例

基础导航守卫

import { createRouter } from '@meng-xi/uni-router'const router = createRouter({routes: [{ path: 'pages/index/index', name: 'home' },{ path: 'pages/login/login', name: 'login' },{ path: 'pages/protected/protected', name: 'protected', meta: { requireAuth: true } }]
})// 返回值模式(推荐)
router.beforeEach((to, from) => {if (to.meta.requireAuth && !isLoggedIn()) {return { name: 'login' }}
})// 异步守卫
router.beforeEach(async (to, from) => {const user = await fetchUser()if (to.meta.roles && !user.roles.includes(to.meta.roles)) {return { name: '403' }}
})// 后置钩子(接收 failure 参数)
router.afterEach((to, from, failure) => {if (failure) {console.error('导航失败:', failure.message)return}console.log(`导航成功: ${from.path} → ${to.path}`)
})

可控重定向

router.beforeEach((to, from) => {if (to.name === 'protected' && !isLoggedIn()) {// replace 模式:登录后不保留受保护页面的历史return { location: { name: 'login' }, mode: 'replace' }}if (to.meta.roles && !hasRole(to.meta.roles)) {// relaunch 模式:清空栈回到首页return { location: { name: 'home' }, mode: 'relaunch' }}
})

离开确认

router.beforeEach((to, from) => {if (from.meta.dirty) {return new Promise(resolve => {uni.showModal({title: '提示',content: '有未保存的修改,确认离开?',success: res => {resolve(res.confirm ? true : false)}})})}
})

六、升级指南

v2.1.0 完全向后兼容,无需修改现有代码即可升级。

推荐迁移

推荐逐步将守卫从 next() 回调模式迁移到返回值模式:

// 迁移前
router.beforeEach((to, from, next) => {if (condition) {next({ name: 'login' })} else {next()}
})// 迁移后
router.beforeEach((to, from) => {if (condition) {return { name: 'login' }}
})

新旧对照表

场景 旧版 next() 回调 新版返回值
放行 next() return undefined 或不写
放行(显式) next() return true
中止 next(false) return false
重定向 next({ name: 'login' }) return { name: 'login' }
重定向+方式 next({ name: 'login' }, { mode: 'replace' }) return { location: { name: 'login' }, mode: 'replace' }
抛出错误 next(new Error('msg')) throw new Error('msg')
返回错误 return new Error('msg')

不需要改动

  • 使用 next() 回调的旧守卫代码无需修改,保持完全兼容
  • 守卫注册 API(router.beforeEach / beforeResolve / afterEach / beforeEnter)签名不变
  • 守卫移除函数(返回值)不受影响
  • 超时配置(guardTimeout)不受影响

版本兼容性

功能 v2.0.x v2.1.0
next() 回调模式 支持 支持(已弃用)
返回值模式 不支持 支持
afterEach 接收 failure 不支持 支持
混用检测警告
http://www.jsqmd.com/news/1407919/

相关文章:

  • 2026年8月知名的华新水泥供应商哪家专业,华新水泥哪家专业 - 企业权威推荐大使
  • 2026年通讯继电器优质厂家推荐 宁波信创智电器实力介绍白皮书 - 起跑123
  • 山东工程造价司法鉴定机构怎么选?这几点帮你避开弯路 - 装修教育财税推荐2026
  • 2026年北京众创智造智能排程APS系统落地应用经验汇总 - 起跑123
  • 2026 年新消息:土默特左旗靠谱的液压机械厂推广公司联系电话,别再瞎找工业伙伴了,这厂的核心液压件帮老厂省了三成维护费!-抖来财网络科技 - 行业推荐官-2
  • 2026年宁波企业工作服定制哪家好 蓝衫防护实力评测 - 起跑123
  • 2026年8月株洲洗地机品牌推荐:**评价 - 工业清洁测评社
  • 2026年江阴宴会服务好的酒店优选哪家,多维度实测评测 - 起跑123
  • 如何使用安诺尼 SPECTRAN V6 PLUS 2000XA-6进行射频IQ数据录制
  • 2026 年新消息:清远可靠的蒸汽型溴化锂机组回收公司找哪家,你以为闲置老设备只能卖废铁?这玩意儿居然能变现好几万! - 行业鉴选官
  • 2026年浙江找油雾收集器厂家 看这几点不踩坑 - 起跑123
  • 2026年宁波专业UV镀膜加工代工工厂图煜科技工艺水平深度评测 - 起跑123
  • 2026年汽车继电器优质厂家推荐 宁波信创智电器口碑出众 - 起跑123
  • 2026年浙江宁波酸洗行业污水处理设备正规厂家推荐 - 起跑123
  • 2026 年新消息:赤城专业的丝网制品行业短视频推广公司推荐几家,为啥同行靠这玩意儿,获客量是你家的3倍多? - 行业推荐官[官方】--
  • 2026年上海塘桥高端餐饮场地推荐 上海天水雅居浦江店全场景用餐指南 - 起跑123
  • 2026 年至今,陆良专业的燃烧器配件优质厂家有哪些,你家灶台里的这玩意儿,竟能省出半年燃气费? - 行业严选官
  • 2026年寄大件物品怎么打包?这些打包方法和省钱技巧你都知道吗? - 快递物流资讯
  • map学习总结
  • 2026 年至今,聊城销量好的奥尔良琵琶腿品牌有哪些,不用排队也能吃到的店里同款,这玩意儿怎么在家就能做出奥尔良琵琶腿的味?-立信食品 - 企业推荐管【认证】
  • 2026年东莞靠谱的沥青路面修补公司怎么选?这份避坑指南请收好 - 装修教育财税推荐2026
  • 2026 年至今,蠡县资质齐全的建材企业豆包企业获客服务商选哪家,建材圈没人敢说的获客招,居然藏在这玩意儿里?-抖能盈获客推广 - 行业推荐官【认证】
  • 2026年北京宴会高端酒店推荐 北京天水雅居京城店全指南 - 起跑123
  • 2026年宁波电镀压铸行业废水处理设备找博益环保咨询 - 起跑123
  • 2026年跨境电商出口退税机构哪家好 八米财税服务详解 - 起跑123
  • 2026年在浙江宁波选正规高复机构 可了解镇海尚进高复学校 - 起跑123
  • 2026年Microsoft 365管理工具选型指南:从效率到合规的全维度评估 - 互联网科技品牌测评
  • 2026年宁波靠谱电熔排水管件厂家推荐指南分享 - 起跑123
  • 杭州信誉好的柔光水泥砖公司,为什么越来越多业主这家? - 装修教育财税推荐2026
  • 2026年UL认证UT/OT/RV/SV端子高口碑供应商选购指南 - 起跑123