# uni-mini-router 在UniApp中的整合教程
## 一、uni-mini-router简介
uni-mini-router是一个轻量级的路由管理库,专为uni-app设计,解决了uni-app原生路由系统中没有路由拦截等关键功能的问题。它提供了类似Vue Router的API体验,使得在uni-app项目中实现更加灵活和强大的路由管理成为可能。
### 主要特点
1. **Vue Router风格API**:提供与Vue Router相似的API,降低学习成本
2. **路由拦截功能**:支持全局导航守卫,可以在路由跳转前后执行逻辑
3. **优雅的参数传递**:支持params和query方式传参
4. **命名路由**:支持通过路由名称进行导航
5. **类型支持**:完整的TypeScript类型定义
6. **轻量级**:体积小,性能高效
## 二、安装与基本配置
### 1. 安装uni-mini-router
使用npm或yarn安装uni-mini-router:
```bash
pnpm add - uni-mini-router
```
### 2. 初始化路由
在项目中创建router目录并初始化路由配置:
```typescript
// src/router/index.ts
import { createRouter } from "uni-mini-router";
import { pages, subPackages } from "virtual:uni-pages";
// 生成路由配置
function generateRoutes() {
const routes = pages.map((page) => {
const newPath = `/${page.path}`;
return { ...page, path: newPath };
});
// 处理分包路由
if (subPackages && subPackages.length > 0) {
subPackages.forEach((subPackage) => {
const subRoutes = subPackage.pages.map((page: any) => {
const newPath = `/${subPackage.root}/${page.path}`;
return { ...page, path: newPath };
});
routes.push(...subRoutes);
});
}
return routes;
}
// 创建路由实例
const router = createRouter({
routes: generateRoutes(),
});
export default router;
```
### 3. 在main.ts中挂载路由
```typescript
// src/main.ts
import { createSSRApp } from "vue";
import App from "./App.vue";
import router from "./router";
export function createApp() {
const app = createSSRApp(App);
// 使用路由
app.use(router);
return {
app,
};
}
```
### 4. 配置自动导入(可选,推荐)
使用unplugin-auto-import插件可以自动导入路由相关hooks,无需每次手动导入:
```typescript
// vite.config.ts
import AutoImport from "unplugin-auto-import/vite";
export default defineConfig({
plugins: [
AutoImport({
imports: [
"vue",
{
from: "uni-mini-router",
imports: ["createRouter", "useRouter", "useRoute"],
},
],
dts: "src/auto-imports.d.ts",
}),
],
});
```
## 三、路由基本用法
### 1. 编程式导航
uni-mini-router提供了多种导航方法:
```typescript
const router = useRouter();
// 字符串路径导航
router.push("/pages/index/index");
// 对象导航(通过路径)
router.push({ path: "/pages/index/index" });
// 对象导航(通过名称)
router.push({ name: "index" });
// 携带参数
router.push({
path: "/pages/detail/index",
query: { id: 10 },
});
// 通过名称 + 参数
router.push({
name: "detail",
params: { id: 10 },
});
// Tab页面导航
router.pushTab("/pages/home/index");
// 关闭当前页面并跳转
router.replace("/pages/index/index");
// 关闭所有页面并跳转
router.replaceAll("/pages/index/index");
// 返回上一级
router.back();
// 返回多级
router.back(2);
```
### 2. 获取和使用路由信息
```typescript
const route = useRoute();
// 访问当前路由信息
console.log(route.path); // 当前路由路径
console.log(route.name); // 当前路由名称
console.log(route.query); // 查询参数
console.log(route.params); // 路由参数
```
### 3. 接收页面参数
在页面组件中接收传递的参数:
```typescript
```
> ⚠️ **重要说明**:在uni-mini-router中,params和query参数都会转换为查询字符串放在URL中,两者在实际效果上没有区别。这种设计是为了与Vue Router保持API一致性。
## 四、导航守卫
uni-mini-router提供了全局导航守卫功能,可以在路由跳转前后执行自定义逻辑。
### 1. 全局前置守卫
```typescript
// src/router/index.ts
router.beforeEach((to, from, next) => {
console.log("路由跳转:", from.path, "->", to.path);
// 检查是否需要登录
if (to.meta && to.meta.requireAuth) {
// 检查登录状态
const isLoggedIn = uni.getStorageSync("token");
if (!isLoggedIn) {
// 未登录,跳转到登录页
uni.showToast({ title: "请先登录", icon: "none" });
next("/pages/login/index");
return;
}
}
// 继续导航
next();
});
```
### 2. 全局后置守卫
```typescript
// src/router/index.ts
router.afterEach((to, from) => {
console.log("路由跳转完成:", to.path);
// 可以在这里做一些统计或记录
});
```
### 3. 路由元数据配置
可以在页面文件中使用``自定义块来定义路由元数据:
```vue
{
"name": "protected-page",
"meta": {
"requireAuth": true,
"title": "需要登录的页面"
}
}
```
## 五、实战示例:登录权限控制
### 1. 定义带有权限控制的路由
```typescript
// src/router/index.ts
import { createRouter } from "uni-mini-router";
const router = createRouter({
routes: generateRoutes(),
});
// 全局前置守卫
router.beforeEach((to, from, next) => {
// 检查页面是否需要登录
if (to.meta && to.meta.requireAuth) {
const token = uni.getStorageSync("token");
if (!token) {
// 显示登录提示
uni.showModal({
title: "提示",
content: "该功能需要登录后使用",
confirmText: "去登录",
cancelText: "返回",
success: (res) => {
if (res.confirm) {
// 记住原来要去的页面
uni.setStorageSync("redirect", to.fullPath);
next("/pages/login/index");
} else {
// 取消则返回首页
next("/pages/index/index");
}
},
});
return;
}
}
// 继续导航
next();
});
export default router;
```
### 2. 登录成功后跳转回原页面
```vue
```
## 六、最佳实践与性能优化
### 1. 合理使用跳转方式
- **router.push**:需要保留当前页面、可返回时使用
- **router.replace**:不需要返回当前页面时使用
- **router.replaceAll**:需要清除所有页面栈时使用(如登录后)
- **router.pushTab**:跳转到tabBar页面时使用
### 2. 参数传递最佳实践
- 对于简单数据,直接使用参数传递
- 对于复杂数据或对象,可使用以下方法:
```typescript
// 传递复杂对象
const complexData = { name: "product", details: { id: 1, features: ["a", "b"] } };
// 方法1: JSON序列化 + URL编码
router.push({
path: "/pages/detail/index",
query: { data: encodeURIComponent(JSON.stringify(complexData)) },
});
// 接收页面
onLoad((option) => {
if (option.data) {
try {
const data = JSON.parse(decodeURIComponent(option.data));
console.log(data);
} catch (e) {
console.error("参数解析错误", e);
}
}
});
// 方法2: 对于非常大的数据,考虑使用全局状态管理或本地存储
```
### 3. 路由懒加载
uni-mini-router自动支持小程序的分包加载特性,可以在pages.json中配置分包:
```json
{
"pages": [
// 主包页面
],
"subPackages": [
{
"root": "pages/module",
"pages": [
{
"path": "detail/index",
"style": {
"navigationBarTitleText": "详情页"
}
}
]
}
]
}
```
## 七、路由调试与测试
### 1. 路由日志记录
```typescript
// src/router/index.ts
router.beforeEach((to, from, next) => {
console.log(`[Router] ${from.path || "初始页面"} -> ${to.path}`, {
params: to.params,
query: to.query,
});
next();
});
```
### 2. 常见问题解决
1. **路由参数获取不到**:
- 检查传参方式是否正确
- 使用`console.log`打印完整的option对象
- 尝试同时检查route.query和route.params
2. **页面未注册**:
- 确保页面已在pages.json中正确注册
- 检查路径大小写是否正确
3. **导航守卫不生效**:
- 确保在路由配置后调用守卫
- 检查是否正确调用next()函数
## 总结
uni-mini-router为uni-app提供了Vue Router风格的路由解决方案,特别是增加了路由拦截功能,解决了uni-app原生路由的限制。通过简单配置,就能在uni-app中实现更加灵活的路由管理,包括权限控制、参数传递和路由拦截等高级功能。
使用uni-mini-router可以让你的uni-app项目路由管理更加规范化和工程化,提升开发效率和代码质量。
参考资料:
- [uni-mini-router GitHub仓库](https://github.com/Moonofweisheng/uni-mini-router)
- [uni-mini-router官方文档](https://moonofweisheng.github.io/uni-mini-router/)
- [uni-app官方路由文档](https://uniapp.dcloud.net.cn/tutorial/page.html)