Skip to content

RouterOptions

路由器初始化选项,传递给 createRouter()

类型定义

ts
interface RouterOptions {
  routes: RouteConfig[]
  strict?: boolean
  interceptUniApi?: boolean
  guardTimeout?: number
  readyTimeout?: number
  paramsPersistent?: boolean
  useUniEventChannel?: boolean
}

属性详解

routes

  • 类型: RouteConfig[]
  • 必填: 是
  • 说明: 路由配置列表,需与 pages.json 中的页面声明保持一致

必须与 pages.json 一致

uni-app 的页面由 pages.json 静态声明,Uni Router 不会自动注册页面。routes 中的 path 必须能在 pages.json 中找到对应声明,否则导航会失败。

建议使用 @meng-xi/vite-plugin 自动生成路由配置,避免手动维护不一致。

ts
const routes: RouteConfig[] = [
  { path: 'pages/index/index', name: 'home', meta: { title: '首页', isTab: true } },
  { path: 'pages/about/about', name: 'about', meta: { title: '关于' } }
]

const router = createRouter({ routes })

strict

  • 类型: boolean
  • 默认值: true
  • 说明: 是否启用严格模式
    • true:未匹配的命名路由将抛出 ROUTE_NOT_FOUND 错误
    • false:未匹配的命名路由仅输出警告,并使用名称作为路径回退
ts
// 严格模式(推荐生产环境)
const router = createRouter({ routes, strict: true })

// 宽松模式(迁移阶段或原型开发)
const router = createRouter({ routes, strict: false })

何时关闭严格模式

  • 迁移阶段:逐步迁移到命名路由,未迁移的部分回退为路径
  • 快速原型:不关心路由配置完整性
  • 生产环境建议保持 true,尽早发现配置错误

interceptUniApi

  • 类型: boolean
  • 默认值: false
  • 说明: 是否拦截 uni 原生导航 API(navigateTo / redirectTo / switchTab / reLaunch / navigateBack

启用后直接调用 uni.navigateTo() 等方法将被拦截并转由路由器处理,确保路由守卫(beforeEach / beforeResolve / afterEach)始终生效。

ts
const router = createRouter({
  routes,
  interceptUniApi: true // 拦截原生 API
})

启用后的副作用

  1. 直接调用 uni.navigateTo() 等方法的 success / fail 回调将不会被触发(原始调用被阻止后转由路由器执行)
  2. H5 平台 TabBar 点击会触发 uni.switchTab,已做特殊处理:放行原始调用并在 success 中同步路由状态
  3. 建议统一使用 router.push() / router.replace() / router.back() 进行导航

何时启用

  • 需要确保所有导航都经过守卫(如权限控制)
  • 迁移阶段,逐步替换原生 API 调用
  • 第三方库直接调用 uni.navigateTo 时需要守卫生效

详见拦截器机制

guardTimeout

  • 类型: number
  • 默认值: 10000(10 秒)
  • 说明: 守卫超时时间(毫秒)。当守卫函数在此时间内既未调用 next() 也未返回 rejected Promise 时,将输出警告并自动中止导航以防止永久挂起
ts
const router = createRouter({
  routes: [...],
  guardTimeout: 30000 // 守卫中异步请求较慢时调大超时
})

调整建议

场景建议值
纯同步守卫10000(默认)
守卫含网络请求30000(30 秒)
守卫含大文件读取60000(60 秒)
禁用超时保护0(不推荐)

设为 0 可禁用超时保护,但可能导致导航永久挂起,不推荐。

readyTimeout

  • 类型: number
  • 默认值: 0(永不超时)
  • 说明: 路由器就绪超时时间(毫秒)。当路由器在此时间内未能完成初始化时,await router.isReady() 将被 reject,防止路由器初始化异常时 Promise 永久挂起
ts
const router = createRouter({
  routes: [...],
  readyTimeout: 5000 // 5 秒内未就绪则 reject isReady() Promise
})

何时配置 readyTimeout

  • 测试环境:设置较短超时(如 5000ms),快速发现初始化问题
  • 生产环境:可保持默认 0(永不超时),或设置较大值(如 30000ms)作为兜底
  • 路由器初始化异常时,isReady() 会永久挂起,设置超时可避免此问题

paramsPersistent

  • 类型: boolean
  • 默认值: false
  • 说明: 页面参数持久化默认值
    • true:所有 params 默认通过 uni.setStorageSync 持久化存储,H5 刷新后仍可读取
    • falseparams 仅存储在内存中,页面关闭后数据丢失
    • 单次导航可通过 persistent 选项覆盖此默认值
ts
// 全局默认持久化
const router = createRouter({
  routes: [...],
  paramsPersistent: true
})

// 单次导航覆盖(不持久化)
await router.push({
  path: '/detail',
  params: { id: 123 },
  persistent: false
})

// 单次导航覆盖(持久化)
await router.push({
  path: '/detail',
  params: { id: 123 },
  persistent: true
})

持久化的代价

持久化会写入 storage,频繁使用大对象会增加存储开销。建议:

  • 仅在需要 H5 刷新后恢复数据的场景启用
  • 大对象优先使用内存模式(persistent: false
  • 持久化的 params 应及时清理(router 会在页面关闭时自动清理)

useUniEventChannel

  • 类型: boolean
  • 默认值: false
  • 说明: 是否使用内置通信管理器替代 uni.navigateTo 的原生 EventChannel
    • false(默认):push 使用 uni.navigateTo 原生 EventChannel,其他导航方式(replace / relaunch / back)不支持页面通信
    • true:所有导航方式(push / replace / relaunch)都使用内置通信管理器,返回的 eventChannel 均可用

内置通信管理器基于 uni.$emit / uni.$on / uni.$off 全局事件总线实现:

  • 每次导航生成唯一 navigationId 隔离事件通道,避免全局事件冲突
  • 目标页面通过 usePageChannel() 获取通道
  • 粘性事件缓存:emit 总是缓存事件参数,on / once 注册时异步触发,解决导航方 emit 早于目标页面 setup 注册监听器的时序问题
  • __nav_id 通过 URL query 传递并持久化存储,H5 刷新后仍可重建通道
  • 页面卸载时自动清理监听器,防止内存泄漏
ts
const router = createRouter({
  routes,
  useUniEventChannel: true // 所有导航方式支持页面通信
})

// replace / relaunch 现在也返回 eventChannel
const { eventChannel } = await router.replace({ name: 'detail', params: { id: 123 } })
eventChannel.emit('init', { source: 'replace' })

何时启用

  • 需要 replace / relaunch 后与目标页面双向通信
  • 希望统一通信机制,避免原生 EventChannel 的时序问题(emit 早于监听注册导致事件丢失)
  • 需要 H5 刷新后恢复通信通道

与原生 EventChannel 的差异

  • 启用后 push 不再使用 uni.navigateTo 的原生 EventChannel,改用内置通道
  • 目标页面需使用 usePageChannel() 而非 getCurrentPages()[last].getOpenerEventChannel()
  • events 选项仍可用,但通过内置通道转发

详见页面间通信usePageChannel()

完整示例

ts
import { createRouter } from '@meng-xi/uni-router'
import type { RouteConfig } from '@meng-xi/uni-router'

const routes: RouteConfig[] = [
  { path: 'pages/index/index', name: 'home', meta: { title: '首页', isTab: true } },
  { path: 'pages/about/about', name: 'about', meta: { title: '关于', requireAuth: true } },
  { path: 'pages/user/user', name: 'user', meta: { title: '我的', isTab: true } },
  { path: 'pages/login/login', name: 'login', meta: { title: '登录' } }
]

const router = createRouter({
  routes,
  strict: true,              // 严格模式
  interceptUniApi: true,     // 拦截原生 API
  guardTimeout: 15000,       // 守卫超时 15 秒
  readyTimeout: 5000,        // 就绪超时 5 秒
  paramsPersistent: false,   // params 默认不持久化
  useUniEventChannel: false  // 默认仅 push 支持通信
})

export default router

配置组合建议

最小配置(快速原型)

ts
const router = createRouter({
  routes: [
    { path: 'pages/index/index', name: 'home' },
    { path: 'pages/about/about', name: 'about' }
  ]
})

生产环境推荐配置

ts
const router = createRouter({
  routes,
  strict: true,              // 尽早发现配置错误
  interceptUniApi: true,     // 统一守卫流程
  guardTimeout: 15000,       // 适配网络请求
  readyTimeout: 10000,       // 兜底保护
  paramsPersistent: false    // 默认内存模式
})

高安全场景配置

ts
const router = createRouter({
  routes,
  strict: true,
  interceptUniApi: true,     // 确保所有导航经过权限校验
  guardTimeout: 30000,       // 适配复杂权限校验
  readyTimeout: 5000,
  paramsPersistent: false    // 避免敏感数据持久化
})

GuardRouteOptions

router.guardRoute() 方法的选项类型,用于冷启动场景的守卫补执行。

类型定义

ts
interface GuardRouteOptions {
  onAbort?: (failure: NavigationFailure) => void
}

属性

onAbort

  • 类型: (failure: NavigationFailure) => void
  • 说明: 守卫中止时的回调

冷启动场景下页面已加载,无法真正"阻止进入"。当守卫调用 next(false) 中止时,将调用此回调并传入 NavigationFailure 对象。用户可在此回调中执行 router.relaunch() 等操作跳转到安全页面。

ts
router.guardRoute(undefined, {
  onAbort: (failure) => {
    console.warn('冷启动守卫中止:', failure.code)
    // 跳转到安全页面
    router.relaunch({ name: 'home' })
  }
})

守卫结果处理

守卫结果行为
放行(next()不执行导航,resolve 目标路由
重定向(next(location)按守卫指定的方式(默认 relaunch)跳转
中止(next(false)调用 onAbort 回调,并 reject NavigationFailure

详见 Router 实例 - guardRoute()路由守卫 - 冷启动守卫检查

下一步

Released under the MIT License.