Skip to content

介绍

Vue 3 Only

Uni Router 仅支持 uni-app 的 Vue 3 版本,不支持 Vue 2。核心功能依赖 Composition API(inject / ref)、app.provide<script setup> 等特性。

它是什么

Uni Router 是一个为 uni-app 设计的路由管理库,在 uni-app 原生导航 API 之上封装了一层,提供 vue-router 风格的 API 体验。

为什么需要它

uni-app 原生使用 uni.navigateTouni.redirectTouni.switchTab 等 API 进行页面跳转,存在以下痛点:

痛点原生方案Uni Router 方案
缺乏路由守卫无法在导航前拦截beforeEach / beforeResolve / afterEach
无路由元信息无法为路由附加属性meta 字段,支持自定义扩展
API 碎片化手动判断 navigateTo / switchTab根据 meta.isTab 自动选择
缺少组合式 API无法在 setup 中获取路由useRouter() / useRoute()
错误处理不统一回调式,无结构化错误码NavigationFailure + 错误码
参数传递受限仅支持 URL queryParamsPlugin 支持复杂数据 + 持久化

架构概览

理解 Uni Router 的架构,有助于你后续掌握它的所有功能。

┌─────────────────────────────────────────────────────┐
│                   你的应用代码                        │
│         router.push() / useRouter() / ...            │
├─────────────────────────────────────────────────────┤
│                   Uni Router                         │
│  ┌──────────┐  ┌──────────┐  ┌───────────────────┐  │
│  │  导航方法  │  │  路由守卫  │  │  组合式 API / 插件 │  │
│  │ push 等   │→│ beforeEach│  │  useRouter 等     │  │
│  └────┬─────┘  └────┬─────┘  └───────────────────┘  │
│       │             │                                │
│  ┌────▼─────────────▼────┐  ┌───────────────────┐   │
│  │     导航执行引擎        │  │   路由匹配器       │   │
│  │ 守卫链 → API 调用 → 状态│  │  path / name 匹配 │   │
│  └────────┬──────────────┘  └───────────────────┘   │
│           │                                          │
│  ┌────────▼──────────────────────────────────────┐   │
│  │               插件层(按需注册)                 │   │
│  │ ParamsPlugin │ AnimationPlugin │ ChannelPlugin │   │
│  │         InterceptorPlugin │ 自定义插件          │   │
│  └───────────────────────────────────────────────┘   │
│  ┌────────────┐                                      │
│  │  状态同步   │                                      │
│  │ syncRoute  │                                      │
│  └────────────┘                                      │
├─────────────────────────────────────────────────────┤
│              uni-app 原生导航 API                    │
│     uni.navigateTo / redirectTo / switchTab / ...    │
├─────────────────────────────────────────────────────┤
│              uni-app 页面栈(pages.json 声明)        │
└─────────────────────────────────────────────────────┘

分层职责

  1. 应用层:你的代码调用 router.push() 等 API
  2. Uni Router 层:守卫链调度、路由匹配、状态管理
  3. 插件层:ParamsPlugin、AnimationPlugin、ChannelPlugin、InterceptorPlugin 等扩展功能,按需注册
  4. uni-app 层:实际执行页面跳转的原生 API
  5. 页面栈:uni-app 框架管理的页面栈,由 pages.json 静态声明

关键认知

Uni Router 不替代 uni-app 的导航机制,而是在其之上增加了一层"调度层"。所有导航最终仍通过 uni.navigateTo 等 API 执行,因此 uni-app 的所有限制(如 switchTab 不支持 query)依然存在,Uni Router 只是在这些限制之上做了优雅的封装和提示。

核心概念

页面栈

uni-app 维护一个页面栈,最大深度 10 层(小程序限制)。理解页面栈是掌握 Uni Router 的基础:

操作栈变化对应 uni API
push()入栈(+1)uni.navigateTo
replace()替换栈顶uni.redirectTo
relaunch()清空栈后入栈uni.reLaunch
back()出栈(-n)uni.navigateBack
TabBar 切换关闭非 Tab 页uni.switchTab

页面栈深度限制

小程序平台页面栈最大深度为 10 层。超过限制后 navigateTo 会失败。Uni Router 无法突破此限制,建议使用 relaunch() 重置栈,或用 back() 返回后再 push()

路由匹配

Uni Router 支持两种匹配方式:

  • 路径匹配router.push({ path: 'pages/about/about' })
  • 名称匹配router.push({ name: 'about' })

路径会自动规范化(补全前导 /)。名称匹配更安全,重构时只需修改路由配置。

与 vue-router 的区别

uni-app 的页面路径在编译时由 pages.json 确定,不支持动态路由(如 /user/:id)。如需传递参数,使用 queryparams

路由守卫

守卫是 Uni Router 的核心能力,允许在导航前后插入逻辑:

导航触发
  → beforeEach(全局前置)
  → beforeEnter(路由独享)
  → beforeResolve(全局解析)
  → uni API 调用
  → afterEach(全局后置)

守卫可通过 next() 放行、next(false) 中止、next(location) 重定向。详见路由守卫

状态同步

由于物理返回键和浏览器后退不经过路由器,路由器的 currentRoute 可能与实际页面不同步。Uni Router 在 app.use(router) 安装时注入全局 mixin,在每个页面 onShow 时自动调用 syncRoute() 同步路由状态,无需手动处理。

用户按物理返回键
  → uni-app 原生 navigateBack(不经过路由器)
  → 路由器 currentRoute 仍是旧值
  → 页面 onShow 自动触发 syncRoute()(全局 mixin)
  → currentRoute 更新为真实页面

冷启动守卫

当用户通过 H5 URL / 小程序场景值 / App deeplink 直接进入页面时,页面由 uni-app 框架直接加载,不经过路由器导航,守卫(beforeEach 等)未执行。guardRoute() 方法可对当前页面补执行守卫链,按守卫结果决定是否重定向:

ts
router.isReady().then(() => {
  router.guardRoute(undefined, {
    onAbort: () => router.relaunch({ name: 'home' })
  })
})

这是 uni-app 的固有限制

路由器无法拦截物理返回键和浏览器后退。syncRoute() 通过全局 mixin 自动处理同步。guardRoute() 需手动调用,通常在 router.isReady() 回调中执行。详见平台兼容性

设计哲学

  1. 不替代,而是增强:Uni Router 不绕过 uni-app 的导航机制,所有导航最终走原生 API。这保证了跨平台兼容性,也意味着 uni-app 的限制依然生效。

  2. 静态页面模型:uni-app 采用 pages.json 静态声明页面,Uni Router 尊重这一模型,不提供动态路由注册(addRoute / removeRoute)。

  3. 渐进式采用:核心只提供基础导航能力,扩展功能(参数传递、动画、通信、拦截)通过插件按需引入,未注册的插件不会增加包体积和运行时开销。

  4. 类型安全:通过 @meng-xi/vite-plugindts 功能,路由名称和路径可获得自动补全和类型检查。

核心特性一览

  • 🧭 四种导航push / replace / relaunch / back,自动识别 TabBar 页面
  • 🛡️ 完整守卫链beforeEach / beforeResolve / afterEach / beforeEnter
  • 🧊 冷启动守卫guardRoute() 补执行守卫链,处理 H5 URL / 小程序场景值 / App deeplink 直接进入的场景
  • 🔄 可控重定向 — 守卫中 next(location, { mode }) 指定重定向方式
  • 📦 页面参数(ParamsPlugin)— params 传递复杂数据,不暴露 URL,支持持久化
  • 🔢 查询增强queryInt() / queryNumber() / queryBool() 类型解析
  • 📡 页面通信(ChannelPlugin)— events + eventChannel 双向通信,useUniEventChannel 支持所有导航方式
  • 🎬 导航动画(AnimationPlugin)— App 端自定义动画,路由级默认值
  • 🪝 组合式 APIuseRouter() / useRoute() / usePageChannel() 响应式访问
  • API 拦截(InterceptorPlugin)— 可选拦截原生导航 API,统一守卫流程
  • 🛡️ 超时保护guardTimeout / readyTimeout 防止挂起
  • 💪 TypeScript — 完整类型定义 + 智能提示

它不是什么

由于 uni-app 框架限制,以下 vue-router 特性不支持

特性原因
动态路由注册(addRoute / removeRouteuni-app 页面由 pages.json 静态声明
嵌套路由(<router-view>uni-app 无嵌套视图组件
动态路径匹配(/user/:iduni-app 页面路径固定
router.go(n) / router.forward()小程序不支持前进导航
命名视图uni-app 无多视图支持
路由懒加载uni-app 有自己的代码分割机制
History 模式选择uni-app 各端使用不同路由模式

这些限制源于 uni-app 框架本身的设计,而非本库的不足。详见与 vue-router 的差异

下一步

Released under the MIT License.