更新记录
0.8.0(2026-09-27) 下载此版本
新增
- 基于文件的路由生成插件(构建期 dev 工具,随路由库同包分发):
- 页面就近声明
defineUniPage宏(或<route-config lang="jsonc|uts">自定义块),构建期自动生成pages.json(含 tabBar / subPackages)与routes.gen.uts路由表,消除 path / title / tabBar / isTab 双份手工维护 - 优先级链:宏 > 块 > 插件推导(
titleFallback/tabBar配置兜底),字段级合并 - name 自动规范化:末段 camelCase → 冲突回退全路径 camelCase → 终极冲突按
errorStrategy(strict 抛错 / warn 告警) beforeEnter/ meta 扩展经宏声明(UTS 表达式原样注入生成文件,须自包含)preserveRouteChanges(默认开启):重生成时保留你对路由文件的既有修改与自定义路由- pages.json 手写的非页面字段(globalStyle、uniIdRouter 等)重生成时合并保留
- watch:页面新增/删除/修改 200ms 去抖串行重跑两阶段流水线
- 生成
route-name.gen.d.ts(WEB 端RouteNameMap字面量类型)与define-uni-page.d.ts(宏类型声明),均可关闭
- 页面就近声明
- 新增子路径导出
@meng-xi/unix-router/vite-plugin:vite / webpack 适配器(unplugin 打包内置,运行时零额外依赖),node/源码目录在 UTS 编译扫描范围外,主入口 UTS 编译不受影响 - 插件拆分为三个独立实现(
node/重组为route-gen/pages-gen/routes-gen+shared目录),可独立或组合注册、互不影响:routeGen:页面文件 →pages.json+routes.gen.uts全量流水线(行为与此前一致)pagesGen:页面文件 → 仅pages.json(含宏 dts),不触碰路由文件routesGen:pages.json→ 仅路由表,不触碰pages.json;支持扩展声明文件routes.ext.uts(path / name ↔ 显式 name / meta 扩展 / beforeEnter,函数原文注入;router.extensions可改路径或false关闭)- 选项随插件拆分:公共选项(
pagesJsonPath/watch/verbose/errorStrategy)+pages段 /router段
修复
- Android 云打包编译错误(UTS 强类型):
Promise.catch回调参数类型由any调整为any | null:UTS 的any编译为 Kotlin 非空Any,无法匹配UTSPromise.catch要求可空回调参数的重载isNavigationFailure首参签名由Error | null放宽为any | null(内部instanceof收窄),修复.catch((e) => isNavigationFailure(e))链式用法编译失败
- *H5 端 `uni.
导航 API 编译类型警告**:WEB 端导航 options 收敛为统一桥接函数applyWebNavOptions(动态字段经as any桥接),消除uni.navigateTo` 等的编译警告,运行时行为不变 - H5 端
router.push崩溃:pickAnimation/toUniAnimation/pickEvents对可选字段=== null判断后直接取.length/.size,H5(JS 运行时)缺省值是undefined导致TypeError、导航中断;统一?? null归一化后判断 - App 端导航动画透传缺失:
AnimationPlugin此前 App 端实际未透传动画参数,现uni.navigateTo/uni.navigateBack具名 Options 携带animationType/animationDuration(官方类型声明标注仅 App 支持:Android 4.18+ / iOS 4.25+ / HarmonyOS 4.61+);小程序端官方不支持动画字段,redirectTo/reLaunch/switchTab官方 Options 无动画字段,均不携带
0.7.0(2026-09-20) 下载此版本
变更(破坏性)
- 插件注册改为实例化:非蒸汽(原生 Kotlin/Swift)端不支持「对象字面量承载方法」,
RouterPlugin由 type 调整为 abstract class,内置插件改为class ParamsPlugin extends RouterPlugin实现,注册写法从plugins: [ParamsPlugin]变更为plugins: [new ParamsPlugin()](Interceptor / Animation / Events 三个插件同理)
修复
- 非蒸汽(原生)编译全链路兼容:
- 含方法的对象字面量 class 化:
RouteState/GuardManager/RouteMatcher/ParamsManager/PluginContext均由「工厂返回对象字面量」重构为 class,消除 Kotlin 端被推断为 UTSJSONObject 导致的方法调用失效 - 条件语句显式布尔化:全库移除 truthy 判断(
if (x)→if (x != null)),符合 UTS 条件必须为布尔值的规范 - uni.* 导航 options 跨端适配:App / 小程序使用无动画字段的对象字面量(匹配
NavigateToOptions具名参数),H5 使用 UTSJSONObject 携带animationType - 变参函数类型兼容:事件回调由
(...args: any[]) => any调整为单参数(data: any) => any(Kotlin 函数类型参数不支持 vararg / 修饰符) - 遍历与类型清理:移除
for..in+Object.prototype遍历(改用UTSJSONObject.keys())、清除undefined标识符与Promise.reject返回类型问题、显式可空参数 - 页面层:模板绑定顶层函数改为本地包装函数(非蒸汽下端顶层函数以属性对象暴露);ucss 复合/后代选择器改为动态 class
- 含方法的对象字面量 class 化:
0.6.0(2026-09-18) 下载此版本
新增
EventsPlugin页面间事件通信插件(opt-in,plugins: [EventsPlugin]):- 对齐 uni-app 官方
navigateTo的events语义:打开方push携带events监听表,被打开页通过useOpenerEventChannel()的EventChannelemit回传数据 /on接收推送 - 底层为自研
eventBus($on/$once/$off/$emit,按 id 移除监听),不受官方uni.$on版本门槛限制 - 通道 key 经内部
__evt__URL 查询串跨页桥接,状态同步时剔除(不暴露给用户);useOpenerEventChannel()不依赖路由同步时机,onShow 内即可使用 - 未注册插件却携带
events的导航抛PLUGIN_REQUIRED,明确引导
- 对齐 uni-app 官方
- 新增导出:
EventsPlugin/eventBus/useOpenerEventChannel - 新增类型:
EventsMap;RawLocation/RouteLocationRaw支持events可选字段
平台兼容性
uni-app x(3.8.4)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| √ | √ | √ | √ |
ux-router
为 uni-app x 提供的、API 对标 vue-router 4 的路由管理库。以 UTS 源码(.uts)形式随 uni_modules 分发,由 uni-app x 编译链按平台现场编译(Web / 小程序 → JS,Android → Kotlin,iOS → Swift),无需预编译。
简介
uni-app x 原生提供 uni.navigateTo / redirectTo / reLaunch / navigateBack / switchTab,但当页面增多后「无路由表、无守卫、无统一路由状态、参数传递繁琐」成为痛点。ux-router 用一套与 vue-router 一致的 API 抹平这些差异,并提供登录鉴权、导航控制、参数传递等能力。
特性
- vue-router 风格 API:
createRouter、push/replace/relaunch/back,自动根据meta.isTab切换switchTab - 路由匹配:path / name 双索引,字符串 / 对象 / 命名三种解析,
strict严格模式 - 路由守卫:
beforeEach/beforeResolve/afterEach/beforeEnter/ 组件内守卫,支持重定向、守卫超时与重定向深度上限 - 组合式 API:
useRouter()/useRoute()/useLink(),响应式currentRoute - 导航控制:重复导航自动拒绝(
DUPLICATED)、并发导航自动排队 - 错误体系:
RouterError/NavigationFailure/UniNavigationApiError,RouterErrorCode错误码,isNavigationFailure()精准判断,onError全局捕获 - 冷启动守卫:
guardRoute()对 H5 直达 / 场景值 / deeplink 补执行守卫链,支持重定向与中止回调(onAbort) - 路由状态同步:页面
onShow自动syncRoute(),物理返回 / TabBar 切换等非路由器导航自动对齐 - 基于文件的路由生成(构建期 dev 工具,opt-in):从 npm 包
@meng-xi/unix-router/vite-plugin(uni_modules 分发版随包附带plugins/适配器)引入 vite 插件,页面就近声明defineUniPage宏,构建期自动生成pages.json与路由表routes.gen.uts,消除 path / title / isTab 双份手工维护;提供routeGen/pagesGen/routesGen三个独立插件 - 插件体系(opt-in,注册须实例化):
- ParamsPlugin 页面参数传递:
params(Map<string,string>)经__params__关联存储跨页传递,键名不暴露明文 - InterceptorPlugin uni API 拦截:
interceptUniApi: true时,直调uni.navigateTo/switchTab等原生导航也转入守卫链 - AnimationPlugin 导航窗口动画:App 端透传原生
animationType/animationDuration(动画字段官方仅 App 支持,小程序端官方不支持、无动画),H5 端通过 WAAPI 播放进入 / 退出动画;支持全局默认(animation选项)与单次覆盖 - EventsPlugin 页面事件通信:对齐官方
navigateTo的events语义,被打开页经useOpenerEventChannel()回传 / 接收数据
- ParamsPlugin 页面参数传递:
目录结构
ux-router/
├── package.json # uni_modules 插件清单(id / displayName / 版本等)
├── changelog.md # 更新日志
├── readme.md # 本说明
├── plugins/ # 构建期文件路由 vite 插件适配器(JS 产物,routeGen / pagesGen / routesGen)
└── utssdk/ # UTS 源码(核心逻辑)
├── index.uts # 公共入口
├── router/ # 路由器(createRouter 主实现)
├── matcher/ # 路由匹配
├── guard/ # 守卫管理
├── history/ # 页面栈适配
├── navigation/ # uni.* 导航封装
├── state/ store/ # 路由状态
├── composables/ # useRouter / useRoute / useLink / useOpenerEventChannel / 组件内守卫
├── plugins/ # 内置插件:params / interceptor / animation / events
├── components/ # RouterLink.uvue 声明式导航组件
├── errors/ enums/ # 错误与错误码
├── types/ # 类型定义
├── utils/ # path / query / params 工具
└── constants/ # 常量
引入方式
本插件为 uni_modules 自包含,无需 npm 安装,直接 import 即可:
import { createRouter } from '@/uni_modules/ux-router/utssdk/index.uts'
快速开始
1. 定义路由配置
path 须与 pages.json 注册的页面路径一致:
import type { RouteConfig } from '@/uni_modules/ux-router/utssdk/index.uts'
export const routes: RouteConfig[] = [
{ path: 'pages/index/index', name: 'home', meta: { title: '首页', isTab: true } },
{ path: 'pages/about/about', name: 'about', meta: { title: '关于', requireAuth: true } }
]
2. 创建路由器
import { createRouter } from '@/uni_modules/ux-router/utssdk/index.uts'
import { routes } from './router.config'
export const router = createRouter({ routes, strict: true })
// 可选:按需注册插件(注册须实例化,0.7.0 起为破坏性变更)
// import { ParamsPlugin, InterceptorPlugin, AnimationPlugin, EventsPlugin } from '@/uni_modules/ux-router/utssdk/index.uts'
// export const router = createRouter({
// routes,
// plugins: [new ParamsPlugin(), new InterceptorPlugin(), new AnimationPlugin(), new EventsPlugin()]
// })
3. 安装到应用
// main.uts
import { createSSRApp } from 'vue'
import App from './App.uvue'
import { router } from './router'
export function createApp() {
const app = createSSRApp(App)
app.use(router) // provide 路由 + 注入全局 mixin(onShow 自动 syncRoute)
return { app }
}
4. 页面内使用
<script setup lang="uts">
import { useRouter, useRoute } from '@/uni_modules/ux-router/utssdk/index.uts'
const router = useRouter()
const route = useRoute()
function go() {
router.push({ name: 'about', query: new Map([['from', 'home']]) })
}
</script>
路由选项
createRouter 支持以下常用选项:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
routes |
RouteConfig[] |
- | 路由配置,需与 pages.json 声明一致 |
strict |
boolean |
true |
严格模式,未匹配的命名路由抛出 RouterError |
guardTimeout |
number |
10000 |
守卫超时(ms),超时警告并自动中止导航,设 0 关闭 |
readyTimeout |
number |
0 |
就绪超时(ms),防止 await router.isReady() 挂起 |
plugins |
RouterPlugin[] |
- | 可选插件列表,传入实例:[new ParamsPlugin()] / [new InterceptorPlugin()] / [new AnimationPlugin()] / [new EventsPlugin()] |
paramsPersistent |
boolean |
false |
是否默认将 params 持久化到 storage(需配合 ParamsPlugin) |
interceptUniApi |
boolean |
false |
opt-in:拦截 uni.* 原生导航,使直调也走守卫链(运行时版本要求:Web 4.0 / 微信 4.41 / Android 3.97 / iOS 4.11 / Harmony 4.61,需配合 InterceptorPlugin) |
animation |
NavigationAnimation |
- | 全局默认导航动画 { type, duration }(需配合 AnimationPlugin 才生效) |
路由导航
| 方法 | 对应原生 API | 行为 |
|---|---|---|
router.push(location) |
uni.navigateTo / switchTab |
保留当前页,推入新页 |
router.replace(location) |
uni.redirectTo / switchTab |
替换当前页 |
router.relaunch(location) |
uni.reLaunch / switchTab |
关闭所有页,打开目标 |
router.back(delta) |
uni.navigateBack |
返回上一页或多级 |
await router.push({ name: 'about', query: new Map([['a', '1']]) })
await router.replace('/pages/detail/detail')
await router.relaunch('/pages/index/index')
await router.back() // 返回一页
await router.back(2) // 返回两级
目标为 meta.isTab 的路由会自动使用 uni.switchTab。
路由守卫
router.beforeEach((to, from) => {
if (to.meta.requireAuth === true && !isLoggedIn()) {
return { name: 'login', query: new Map([['redirect', to.fullPath]]) } // 重定向
}
return true // null / true 放行
})
router.afterEach((to, from, failure) => {
console.log(`导航: ${from.fullPath} -> ${to.fullPath}`, failure?.message ?? '')
})
// 组件内离开守卫(返回 false 阻止离开)
import { onBeforeRouteLeave } from '@/uni_modules/ux-router/utssdk/index.uts'
onBeforeRouteLeave((to, from) => hasUnsavedChanges ? false : true)
守卫全集:beforeEach / beforeResolve / afterEach / beforeEnter / onBeforeRouteLeave / onBeforeRouteEnter / onBeforeRouteUpdate,以及冷启动补执行 guardRoute()。
冷启动(H5 直达 / 场景值 / deeplink)时页面已加载、守卫未执行,可补跑守卫链:
router.isReady().then(() => {
router.guardRoute(undefined, {
: () => router.relaunch('/pages/index/index') // 守卫中止时转跳安全页
})
})
参数传递
query:URL 可见,适合少量、简单、可分享的数据params:经 ParamsPlugin(__params__关联存储)跨页传递,键名不暴露明文,适合命名参数(需注册plugins: [new ParamsPlugin()])
两者均为 Map<string,string>:
import { queryInt, queryBool } from '@/uni_modules/ux-router/utssdk/index.uts'
router.push({ name: 'detail', params: new Map([['id', '42'], ['from', '首页']]) })
// 目标页读取(Map API)
const route = useRoute()
const id = route.params.get('id') ?? '' // "42"
// query 读取同样用 Map API,配合工具函数便捷解析
const from = route.query.get('utm') ?? '' // query 用 .query.get
const idNum = queryInt(route.query, 'id', 0) // 便捷解析数值
const flag = queryBool(route.query, 'vip', false) // 便捷解析布尔
复杂对象请先
JSON.stringify,或改用全局状态 /uni.setStorageSync承载。
组合式 API
useRouter():获取路由器实例useRoute():响应式当前路由(脚本/模板直接访问字段,如route.path/route.query.get())useLink():声明式导航的响应式状态与触发(isActive/navigate等),配套RouterLink组件直接使用useOpenerEventChannel():获取打开方事件通道(需EventsPlugin),不依赖路由同步时机,onShow内即可使用
API 概览
| 分类 | 内容 |
|---|---|
| 创建 | createRouter(options) |
| 导航 | push / replace / relaunch / back |
| 守卫 | beforeEach / beforeResolve / afterEach / beforeEnter |
| 组合式 | useRouter / useRoute / useLink / useOpenerEventChannel / onBeforeRouteLeave/Enter/Update |
| 查询 | getRoutes / hasRoute / resolve / currentRoute / isReady |
| 同步/扩展 | syncRoute / guardRoute / onError / onRouteChange |
| 插件 | ParamsPlugin / InterceptorPlugin / AnimationPlugin / EventsPlugin / eventBus(注册须实例化) |
| 组件 | RouterLink(声明式导航) |
| 错误 | RouterError / NavigationFailure / RouterErrorCode / isNavigationFailure |
完整 API 与「从入门到精通」教程见仓库
packages/docs。
平台兼容性
- Web / H5、微信小程序:编译为 JS
- App-Android / App-HarmonyOS(VDOM / 蒸汽模式):编译为 Kotlin / JS(HarmonyOS 需 HBuilderX 4.61+)
- App-iOS:编译为 Swift
- 底层仅依赖
uni.*原生导航 API(navigateTo / redirectTo / reLaunch / navigateBack / switchTab) - 导航动画字段官方仅 App 支持(Android 4.18+ / iOS 4.25+ / HarmonyOS 4.61+),小程序端官方不支持;H5 端由 AnimationPlugin 以 WAAPI 实现
- 物理返回键 / TabBar 切换不经过路由器,通过
syncRoute()在onShow自动对齐

收藏人数:
https://github.com/MengXi-Studio/unix-router
https://www.npmjs.com/package/@meng-xi/unix-router
下载插件并导入HBuilder
下载示例项目ZIP
赞赏(0)
下载 80
赞赏 0
下载 12701468
赞赏 1957
赞赏
京公网安备:11010802035340号