@meng-xi/uni-router
Version:
为 uni-app 提供类似 vue-router 风格的路由
458 lines (341 loc) • 16.1 kB
Markdown
# @meng-xi/uni-router
 


`@meng-xi/uni-router` 是一个专为 uni-app 开发的路由管理库,采用类似 `vue-router` 的设计风格,并提供丰富的工具函数,帮助开发者轻松实现跨平台路由管理。
## 目录
- [核心功能](#核心功能)
- [安装指南](#安装指南)
- [快速入门](#快速入门)
- [实例化使用](#实例化使用)
- [类使用](#类使用)
- [API 参考](#api-参考)
- [Router 类](#router-类)
- [实用工具](#实用工具)
- [Hooks](#hooks)
- [组件](#组件)
- [配置](#配置)
- [Router 组件](#router组件)
- [错误处理](#错误处理)
- [贡献指南](#贡献指南)
- [许可证](#许可证)
## 核心功能
- **类 `vue-router` API**:与 `vue-router` 相似的 API 设计,学习成本低,迁移简单
- **多种导航方式**:
- `push`:保留当前页面的跳转
- `replace`:替换当前页面
- `launch`:重启应用并跳转
- `tab`:切换 tabBar 页面
- `go`/`back`:页面返回控制
- **路由守卫**:
- `beforeEach`:导航前执行(适合权限验证)
- `afterEach`:导航后执行(适合埋点统计)
- **实用方法**:
- `getCurrentRoute`: 获取当前路由信息
- `setCustomGetCurrentRoute`: 设置自定义获取当前路由的函数
- **实用工具**:
- `parseLocation`:解析路由位置
- `buildUrl`:构建完整 URL
- `getCurrentRoute`:获取当前路由
- **Hooks**:
- `useMxRouter`:获取 Router 实例
- **组件**:
- `Router`:路由组件
- **全平台适配**:完美支持 H5、小程序和 App
## 安装指南
使用 `pnpm` 安装:
```bash
pnpm install @meng-xi/uni-router
```
## 快速入门
#### 初始化路由
```typescript
import { Router } from '@meng-xi/uni-router'
const router = new Router({
routes: [
{ path: '/home', meta: { title: '首页' } },
{ path: '/admin', meta: { requiresAuth: true } }
]
})
```
#### 配置路由守卫
```typescript
// 认证状态检查
const isAuthenticated = () => !!localStorage.getItem('token')
// 前置守卫
router.beforeEach((to, from, next) => {
if (to.meta?.requiresAuth && !isAuthenticated()) {
next({ path: '/login', query: { redirect: to.fullPath } })
} else {
next()
}
})
// 后置钩子
router.afterEach((to, from) => {
console.log(`从 ${from?.path || '起始页'} 跳转到 ${to.path}`)
})
```
#### 路由跳转示例
```typescript
// 基本跳转
router.push('/products')
// 带参数跳转
router.push({
path: '/search',
query: { keyword: '手机' }
})
// 替换当前页
router.replace('/profile')
// 重启跳转
router.launch('/dashboard')
// 切换 tab 页
router.tab('/tabBar/cart')
// 页面返回
router.back()
router.go(-2)
```
### 单例模式
#### 创建单例
```typescript
import { Router } from '@meng-xi/uni-router'
Router.getInstance({
routes: [
{ path: '/home', meta: { title: '首页' } },
{ path: '/admin', meta: { requiresAuth: true } }
]
})
```
#### 守卫配置
```typescript
Router.beforeEach((to, from, next) => {
if (to.meta?.requiresAuth && !isAuthenticated()) {
next({ path: '/login', query: { redirect: to.fullPath } })
} else {
next()
}
})
Router.afterEach((to, from) => {
console.log(`路由跳转: ${from?.path || '起始页'} → ${to.path}`)
})
```
#### 导航操作
```typescript
Router.push('/products')
Router.push({ path: '/search', query: { keyword: '手机' } })
Router.replace('/profile')
Router.launch('/dashboard')
Router.tab('/tabBar/cart')
Router.back()
Router.go(-2)
```
## API 参考
### Router 类
实现 `RouterInterface` 接口,提供核心路由功能。
#### 构造函数
```typescript
constructor(options?: RouterOptions)
```
参数说明:
- `options`(可选):包含 `routes` 路由配置数组和 `customGetCurrentRoute` 自定义获取当前路由的函数的对象。
#### 导航方法
| 方法 | 说明 | 参数 | 返回值 |
| --------- | ---------------------- | ---------------------------- | --------------- |
| `push` | 保留当前页面的跳转 | `location: RouteLocationRaw` | `Promise<void>` |
| `replace` | 替换当前页面 | `location: RouteLocationRaw` | `Promise<void>` |
| `launch` | 重启应用跳转 | `location: RouteLocationRaw` | `Promise<void>` |
| `tab` | 切换 tab 页面 | `location: RouteLocationRaw` | `Promise<void>` |
| `go` | 返回指定层数(默认-1) | `delta?: number` | `void` |
| `back` | 返回上一页 | - | `void` |
#### 路由守卫
| 方法 | 说明 | 参数 | 返回值 |
| ------------ | ------------ | ------------------------ | ------ |
| `beforeEach` | 全局前置守卫 | `guard: NavigationGuard` | `void` |
| `afterEach` | 全局后置钩子 | `hook: AfterEachHook` | `void` |
#### 实用方法
| 方法 | 说明 | 参数 | 返回值 |
| -------------------------- | ---------------------------- | ------------------------------------- | --------------- |
| `getCurrentRoute` | 获取当前路由信息 | - | `RouteLocation` |
| `setCustomGetCurrentRoute` | 设置自定义获取当前路由的函数 | `customFunction: () => Route \| null` | `void` |
### 实用工具
#### `parseLocation`
```typescript
parseLocation(location: RouteLocationRaw): { path: string; query?: Record<string, string> }
```
- **功能**:将路由位置信息统一解析为路径和查询参数对象
- **参数**:
- `location`:支持字符串或对象格式的路由位置信息
- **返回**:包含路径字符串和可选查询参数的对象
#### `buildUrl`
```typescript
buildUrl(path: string, query?: Record<string, string | number | boolean>): string
```
- **功能**:根据路径和查询参数构建完整 URL
- **参数**:
- `path`:目标路径字符串
- `query`(可选):查询参数对象
- **返回**:完整的 URL 字符串
#### `getCurrentRoute`
```typescript
getCurrentRoute(currentPage: CurrentPage | null): Route | null
```
- **功能**:获取当前页面的路由信息(支持多平台差异处理)
- **参数**:
- `currentPage`:当前页面实例(可为 null)
- **返回**:当前路由对象或 null(获取失败时)
## Hooks
### `useMxRouter` 用于管理 `Router` 组件实例并提供操作方法
注意:该 `Hook` 只支持 `vue3` 版本
```vue
<template>
<mx-router @register="register">首页</mx-router>
</template>
<script setup lang="ts">
import { useMxRouter } from '@meng-xi/uni-router'
const [register, methods] = useMxRouter({
to: '/pages/index/index'
})
</script>
```
#### 参数
| 属性 | 描述 | 类型 | 默认值 |
| -------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------- | ---------- |
| to | 路由地址 | RouterLinkProps | - |
| method | 跳转方式 | 'push' \| 'replace' \| 'tab' \| 'launch' \| 'back' \| 'exit' | 'push' |
| delta | 回退层数 | number | - |
| animationType | 窗口动画类型 | UniApp.NavigateToOptions['animationType'] & UniApp.NavigateBackOptions['animationType'] | pop-in/out |
| animationDuration | 动画持续时间 | number | 300 |
| renderLink | 是否给 navigator 组件加一层 a 标签控制 ssr 渲染 | boolean | true |
| hoverClass | 自定义悬停样式类名 | string | 'none' |
| hoverStopPropagation | 指定是否阻止本节点的祖先节点出现点击态 | boolean | false |
| hoverStartTime | 按住后多久出现点击态,单位毫秒 | number | 50 |
| hoverStayTime | 手指松开后点击态保留时间,单位毫秒 | number | 600 |
| target | 在哪个小程序目标上发生跳转,值域 self/miniProgram | string | 'self' |
## 组件
### 配置
建议使用 `easycom` 来简化组件的引入和注册
#### NPM
```json
// pages.json
{
"easycom": {
"custom": {
"^mx-(.*)": "@meng-xi/uni-router/components/$1/$1.vue"
}
}
}
```
#### HBuilderX
如果你是通过插件市场导入到 [`HBuilderX`](https://ext.dcloud.net.cn/plugin?id=24456) 的,需要修改一下组件路径
```json
// pages.json
{
"easycom": {
"custom": {
"^mx-(.*)": "@/js_sdk/PedroQue99-router/PedroQue99-router/components/$1/$1.vue"
}
}
}
```
#### 配置全局组件类型
在 `vscode` 中使用时,为了有组件的类型提示和自动填充,需要配置全局组件类型声明。
```json
// tsconfig.json
{
"compilerOptions": {
"types": ["@meng-xi/uni-router/components/index"]
}
}
```
如果是使用 `WebStorm`,可能需要在 main.ts 文件中导入 index.d.ts 文件。
```typescript
// main.ts
import '@meng-xi/uni-router/components/index.d.ts'
```
### Router 组件
#### 介绍
`Router` 组件用于在应用中进行路由导航。它提供了一种声明式的方式来定义路由链接和导航行为。
#### 引入
```typescript
import Router from '@meng-xi/uni-router/components/router/router.vue'
```
#### 基础用法
```vue
<template>
<mx-router to="/pages/index/index">首页</mx-router>
</template>
```
#### API
##### RouterProps
| 属性 | 描述 | 类型 | 默认值 |
| -------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------- | ---------- |
| to | 路由地址 | RouterLinkProps | - |
| method | 跳转方式 | 'push' \| 'replace' \| 'tab' \| 'launch' \| 'back' \| 'exit' | 'push' |
| delta | 回退层数 | number | - |
| animationType | 窗口动画类型 | UniApp.NavigateToOptions['animationType'] & UniApp.NavigateBackOptions['animationType'] | pop-in/out |
| animationDuration | 动画持续时间 | number | 300 |
| renderLink | 是否给 navigator 组件加一层 a 标签控制 ssr 渲染 | boolean | true |
| hoverClass | 自定义悬停样式类名 | string | 'none' |
| hoverStopPropagation | 指定是否阻止本节点的祖先节点出现点击态 | boolean | false |
| hoverStartTime | 按住后多久出现点击态,单位毫秒 | number | 50 |
| hoverStayTime | 手指松开后点击态保留时间,单位毫秒 | number | 600 |
| target | 在哪个小程序目标上发生跳转,值域 self/miniProgram | string | 'self' |
##### RouterSlots
| 插槽 | 描述 | 属性 |
| ------- | -------------- | ---- |
| default | 自定义默认内容 | - |
## 错误处理
`MxRouterError`类提供以下静态方法创建错误实例:
#### `navigationAborted`
```typescript
static navigationAborted(): MxRouterError
```
- **用途**:创建导航中止错误(用于前置守卫拦截场景)
- **返回**:导航中止错误实例
#### `navigationRedirect`
```typescript
static navigationRedirect(location: string | RouteLocationRaw): MxRouterError
```
- **用途**:创建导航重定向错误(用于路由重定向场景)
- **参数**:
- `location`:重定向目标位置
- **返回**:导航重定向错误实例
#### `navigationFailed`
```typescript
static navigationFailed(message: string): MxRouterError
```
- **用途**:创建导航失败错误(用于导航异常场景)
- **参数**:
- `message`:错误描述信息
- **返回**:导航失败错误实例
#### `invalidMethod`
```typescript
static invalidMethod(method: string): MxRouterError
```
- **用途**:创建无效方法错误(用于调用非法导航方法场景)
- **参数**:
- `method`:无效的方法名称
- **返回**:无效方法错误实例
## 贡献指南
欢迎为 `@meng-xi/uni-router` 贡献代码,步骤如下:
1. Fork 仓库:在 GitHub 上 Fork 本项目。
2. 克隆代码:将 Fork 后的项目克隆到本地。
```bash
git clone https://github.com/your-username/uni-router.git
cd uni-router
```
3. 创建分支:基于 main 分支创建新特性分支。
```bash
git checkout -b feature/your-feature
```
4. 提交更改:确保代码通过测试,提交清晰的 commit 信息。
```bash
git add .
git commit -m "feat: add your feature description"
```
5. 推送分支:将本地分支推送到 GitHub。
```bash
git push origin feature/your-feature
```
6. 创建 PR:在 GitHub 上创建 Pull Request,等待审核。
## 许可证
本项目采用 [MIT 许可证](https://github.com/MengXi-Studio/uni-router/blob/main/LICENSE)。