当 uni-app 的路由管理遇上插件化,会碰撞出怎样的火花?
在 uni-app 生态中,路由管理一直是个让人既爱又恨的话题。原生 API 足够简单,但面对复杂应用时,缺少路由守卫、参数传递繁琐、页面通信不便等问题逐渐浮现。@meng-xi/uni-router 的出现,正是为了给 uni-app 开发者带来类似 vue-router 的现代路由体验。
而 v2.0.0 版本的发布,更是通过插件化架构的重构,将这个库推向了新的高度。
一、什么是 @meng-xi/uni-router?
简单来说,@meng-xi/uni-router 是一个为 uni-app(Vue 3)设计的路由管理库。它不替代 pages.json,而是与之配合,在 uni-app 的静态页面模型之上,构建了一层可控、可扩展的导航管理层。
它的核心设计目标很明确:让 uni-app 开发者用上 vue-router 风格的 API。
二、v2.0:插件化架构,一次彻底的重构
v2.0.0 是该项目的一次重大架构升级。核心变化是:将原本内置的四大功能,拆分成了四个独立的、按需加载的插件。
2.1 四大核心插件
| 插件 | 功能 |
|---|---|
| ParamsPlugin | 页面参数传递,支持传递复杂数据(对象、数组等),不暴露在 URL 中 |
| ChannelPlugin | 页面间通信,所有导航方式(push/replace/relaunch)均支持 eventChannel |
| InterceptorPlugin | 拦截 uni 原生导航 API(navigateTo/redirectTo/switchTab/navigateBack/reLaunch),确保所有跳转都经过路由守卫 |
| AnimationPlugin | 导航动画,push/replace/back 支持动画参数(仅 App 端) |
在 v1.x 中,这些功能是开箱即用的;而在 v2.0 中,你需要显式注册才能使用对应的能力。这带来了两个直接的好处:一是更灵活,你可以按需加载,控制最终包体积;二是架构更清晰,每个插件的职责边界更明确。
2.2 插件系统设计
v2.0 引入了完整的插件接口(RouterPlugin),插件可以注册多达 7 种生命周期钩子,深度介入导航流程:
onEnrichLocation:在路由解析前增强 locationonAfterResolve:路由解析完成后onPrepareNavigation:导航执行前onCompleteNavigation:导航完成后onNavigationAbort:导航被中止时onRouteSync:路由状态同步时onAppInstall:路由器安装到 Vue 应用时
这种设计让插件的扩展能力变得非常强大——开发者甚至可以编写自己的插件来定制路由行为。
三、核心功能全景
除了插件化架构,v2.0 保留了 v1.x 积累的全部核心能力:
3.1 vue-router 风格 API
提供 push、replace、relaunch、back 等熟悉的导航方式:
const router = useRouter()// 路径导航 + query 参数
await router.push({path: '/pages/about/about',query: { id: '1' }
})// 命名路由
await router.push({ name: 'about' })// params 传递复杂数据(需注册 ParamsPlugin)
await router.push({path: '/pages/detail/detail',params: { info: { name: 'Tom' } }
})// 返回上一页
await router.back()
3.2 完整的路由守卫体系
支持全局前置守卫、解析守卫、后置钩子以及路由独享守卫:
router.beforeEach((to, from, next) => {if (to.meta.requireAuth && !isLoggedIn()) {// 重定向到登录页,支持指定跳转模式next({ name: 'login' }, { mode: 'replace' })} else {next()}
})
守卫的 next() 回调支持 mode 参数,可显式指定 'push'、'replace' 或 'relaunch'。
值得一提的是,v2.0 还提供了 guardRoute() 方法,用于解决冷启动场景下守卫不执行的问题——当用户通过 H5 URL 直接访问、小程序扫码或 App deeplink 进入应用时,可以手动调用此方法执行守卫链检查。
3.3 组合式 API
提供 useRouter()、useRoute() 和 usePageChannel() 三个组合式函数:
import { useRouter, useRoute } from '@meng-xi/uni-router'const router = useRouter()
const route = useRoute() // 响应式 Ref,路由变化时自动更新
useRoute() 返回的是响应式引用,当路由变化时组件会自动重新渲染。
3.4 页面间通信:useUniEventChannel
v1.10.0 引入的 useUniEventChannel 在 v2.0 中得以保留和增强。它基于 uni.$emit / $on 全局事件总线实现了一套内置的通信管理器,使得所有导航方式(push、replace、relaunch)均支持双向通信。
3.5 查询参数增强
提供 queryInt()、queryNumber()、queryBool() 便捷方法,自动解析 query 参数为指定类型。
3.6 声明式导航组件
RouterLink 组件支持声明式导航,配合 TabBar / TabBarItem 组件可实现自定义底部导航栏,支持徽标、切换拦截器和 SCSS 主题定制。
3.7 路由状态自动同步
通过 app.use(router) 注入全局 Mixin,在 onShow 时自动调用 syncRoute(),处理浏览器后退、物理返回键等场景。
3.8 完善的错误处理
提供 RouterError、NavigationFailure、UniApiError 错误体系,支持 instanceof 精准判断。
四、快速上手
4.1 安装
pnpm add @meng-xi/uni-router
配合 @meng-xi/vite-plugin 可从 pages.json 自动生成路由配置和 TypeScript 类型声明。
4.2 创建路由器
// src/main.ts
import { createSSRApp } from 'vue'
import { createRouter, ParamsPlugin, ChannelPlugin, InterceptorPlugin } from '@meng-xi/uni-router'
import routes from './router.config'
import App from './App.vue'const router = createRouter({routes,plugins: [ParamsPlugin, ChannelPlugin, InterceptorPlugin], // 按需注册interceptUniApi: true // 需要 InterceptorPlugin
})export function createApp() {const app = createSSRApp(App)app.use(router) // 注入全局 mixinreturn { app }
}
五、版本共存与升级建议
目前,v1.x(最新 v1.11.0)与 v2.x(最新 v2.0.0)两个版本线同时存在:
- 新项目:推荐直接使用 v2.0.0,享受按需加载带来的灵活性
- 现有 v1.x 项目:如果对包体积不敏感或重度依赖默认行为,可继续使用 v1.11.0;如需升级,请务必查阅官方迁移指南,因为这是一次包含破坏性变更的重大升级
六、写在最后
@meng-xi/uni-router v2.0 的插件化架构,标志着这个库从“功能完备”走向了“架构优雅”。它没有试图颠覆 uni-app 的底层设计,而是在 pages.json 的静态模型之上,构建了一个灵活、可扩展的现代化路由层。
对于正在使用 uni-app 进行复杂应用开发的团队来说,这无疑是一个值得认真评估的路由方案。
相关链接:
- GitHub:MengXi-Studio/uni-router
- NPM:
@meng-xi/uni-router- 文档:https://mengxi-studio.github.io/uni-router/