From 7fa0758b19666b7890f262ce4ca31cff26f05218 Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Thu, 24 Jul 2025 20:43:15 +0800 Subject: [PATCH] =?UTF-8?q?wip:=20=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/uniapp整合mini-router.md | 426 ++++++++++++++++++++++++++++++++++ package.json | 1 + src/layouts/tabbar.vue | 5 +- src/router/index.ts | 2 +- src/types/auto-imports.d.ts | 12 +- tsconfig.json | 6 +- vite.config.ts | 2 +- 7 files changed, 442 insertions(+), 12 deletions(-) create mode 100644 docs/uniapp整合mini-router.md diff --git a/docs/uniapp整合mini-router.md b/docs/uniapp整合mini-router.md new file mode 100644 index 0000000..489636f --- /dev/null +++ b/docs/uniapp整合mini-router.md @@ -0,0 +1,426 @@ +# 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) \ No newline at end of file diff --git a/package.json b/package.json index 4e9622e..78e3089 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "@dcloudio/uni-stacktracey": "3.0.0-4020420240722002", "@dcloudio/vite-plugin-uni": "3.0.0-4020420240722002", "@eslint/js": "^9.10.0", + "@uni-helper/uni-types": "1.0.0-alpha.6", "@uni-helper/vite-plugin-uni-components": "^0.2.0", "@uni-helper/vite-plugin-uni-layouts": "^0.1.10", "@uni-helper/vite-plugin-uni-pages": "^0.2.28", diff --git a/src/layouts/tabbar.vue b/src/layouts/tabbar.vue index 7c9bca4..e3311d7 100644 --- a/src/layouts/tabbar.vue +++ b/src/layouts/tabbar.vue @@ -26,14 +26,13 @@