麦歌 發表於 2025-7-25 14:54:00

@meng-xi/uni-router

<p><code>@meng-xi/uni-router</code> 是一个专为 uni-app 开发的路由管理库,采用类似 <code>vue-router</code> 的设计风格,并提供丰富的工具函数,帮助开发者轻松实现跨平台路由管理。</p>
<p>npm包地址<br>
github地址</p>
<h2 id="核心功能">核心功能</h2>
<ul>
<li><strong>类 <code>vue-router</code> API</strong>:与 <code>vue-router</code> 相似的 API 设计,学习成本低,迁移简单</li>
<li><strong>多种导航方式</strong>:
<ul>
<li><code>push</code>:保留当前页面的跳转</li>
<li><code>replace</code>:替换当前页面</li>
<li><code>launch</code>:重启应用并跳转</li>
<li><code>tab</code>:切换 tabBar 页面</li>
<li><code>go</code>/<code>back</code>:页面返回控制</li>
</ul>
</li>
<li><strong>路由守卫</strong>:
<ul>
<li><code>beforeEach</code>:导航前执行(适合权限验证)</li>
<li><code>afterEach</code>:导航后执行(适合埋点统计)</li>
</ul>
</li>
<li><strong>实用方法</strong>:
<ul>
<li><code>getCurrentRoute</code>: 获取当前路由信息</li>
<li><code>setCustomGetCurrentRoute</code>: 设置自定义获取当前路由的函数</li>
</ul>
</li>
<li><strong>实用工具</strong>:
<ul>
<li><code>parseLocation</code>:解析路由位置</li>
<li><code>buildUrl</code>:构建完整 URL</li>
<li><code>getCurrentRoute</code>:获取当前路由</li>
</ul>
</li>
<li><strong>Hooks</strong>:
<ul>
<li><code>useMxRouter</code>:获取 Router 实例</li>
</ul>
</li>
<li><strong>组件</strong>:
<ul>
<li><code>Router</code>:路由组件</li>
</ul>
</li>
<li><strong>全平台适配</strong>:完美支持 H5、小程序和 App</li>
</ul>
<h2 id="安装指南">安装指南</h2>
<p>使用 <code>pnpm</code> 安装:</p>
<pre><code class="language-bash">pnpm install @meng-xi/uni-router
</code></pre>
<h2 id="快速入门">快速入门</h2>
<h4 id="初始化路由">初始化路由</h4>
<pre><code class="language-typescript">import { Router } from '@meng-xi/uni-router'

const router = new Router({
        routes: [
                { path: '/home', meta: { title: '首页' } },
                { path: '/admin', meta: { requiresAuth: true } }
        ]
})
</code></pre>
<h4 id="配置路由守卫">配置路由守卫</h4>
<pre><code class="language-typescript">// 认证状态检查
const isAuthenticated = () =&gt; !!localStorage.getItem('token')

// 前置守卫
router.beforeEach((to, from, next) =&gt; {
        if (to.meta?.requiresAuth &amp;&amp; !isAuthenticated()) {
                next({ path: '/login', query: { redirect: to.fullPath } })
        } else {
                next()
        }
})

// 后置钩子
router.afterEach((to, from) =&gt; {
        console.log(`从 ${from?.path || '起始页'} 跳转到 ${to.path}`)
})
</code></pre>
<h4 id="路由跳转示例">路由跳转示例</h4>
<pre><code class="language-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)
</code></pre>
<h3 id="单例模式">单例模式</h3>
<h4 id="创建单例">创建单例</h4>
<pre><code class="language-typescript">import { Router } from '@meng-xi/uni-router'

Router.getInstance({
        routes: [
                { path: '/home', meta: { title: '首页' } },
                { path: '/admin', meta: { requiresAuth: true } }
        ]
})
</code></pre>
<h4 id="守卫配置">守卫配置</h4>
<pre><code class="language-typescript">Router.beforeEach((to, from, next) =&gt; {
        if (to.meta?.requiresAuth &amp;&amp; !isAuthenticated()) {
                next({ path: '/login', query: { redirect: to.fullPath } })
        } else {
                next()
        }
})

Router.afterEach((to, from) =&gt; {
        console.log(`路由跳转: ${from?.path || '起始页'} → ${to.path}`)
})
</code></pre>
<h4 id="导航操作">导航操作</h4>
<pre><code class="language-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)
</code></pre>
<h2 id="api-参考">API 参考</h2>
<h3 id="router-类">Router 类</h3>
<p>实现 <code>RouterInterface</code> 接口,提供核心路由功能。</p>
<h4 id="构造函数">构造函数</h4>
<pre><code class="language-typescript">constructor(options?: RouterOptions)
</code></pre>
<p>参数说明:</p>
<ul>
<li><code>options</code>(可选):包含 <code>routes</code> 路由配置数组和 <code>customGetCurrentRoute</code> 自定义获取当前路由的函数的对象。</li>
</ul>
<h4 id="导航方法">导航方法</h4>
<table>
<thead>
<tr>
<th>方法</th>
<th>说明</th>
<th>参数</th>
<th>返回值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>push</code></td>
<td>保留当前页面的跳转</td>
<td><code>location: RouteLocationRaw</code></td>
<td><code>Promise&lt;void&gt;</code></td>
</tr>
<tr>
<td><code>replace</code></td>
<td>替换当前页面</td>
<td><code>location: RouteLocationRaw</code></td>
<td><code>Promise&lt;void&gt;</code></td>
</tr>
<tr>
<td><code>launch</code></td>
<td>重启应用跳转</td>
<td><code>location: RouteLocationRaw</code></td>
<td><code>Promise&lt;void&gt;</code></td>
</tr>
<tr>
<td><code>tab</code></td>
<td>切换 tab 页面</td>
<td><code>location: RouteLocationRaw</code></td>
<td><code>Promise&lt;void&gt;</code></td>
</tr>
<tr>
<td><code>go</code></td>
<td>返回指定层数(默认-1)</td>
<td><code>delta?: number</code></td>
<td><code>void</code></td>
</tr>
<tr>
<td><code>back</code></td>
<td>返回上一页</td>
<td>-</td>
<td><code>void</code></td>
</tr>
</tbody>
</table>
<h4 id="路由守卫">路由守卫</h4>
<table>
<thead>
<tr>
<th>方法</th>
<th>说明</th>
<th>参数</th>
<th>返回值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>beforeEach</code></td>
<td>全局前置守卫</td>
<td><code>guard: NavigationGuard</code></td>
<td><code>void</code></td>
</tr>
<tr>
<td><code>afterEach</code></td>
<td>全局后置钩子</td>
<td><code>hook: AfterEachHook</code></td>
<td><code>void</code></td>
</tr>
</tbody>
</table>
<h4 id="实用方法">实用方法</h4>
<table>
<thead>
<tr>
<th>方法</th>
<th>说明</th>
<th>参数</th>
<th>返回值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>getCurrentRoute</code></td>
<td>获取当前路由信息</td>
<td>-</td>
<td><code>RouteLocation</code></td>
</tr>
<tr>
<td><code>setCustomGetCurrentRoute</code></td>
<td>设置自定义获取当前路由的函数</td>
<td><code>customFunction: () =&gt; Route | null</code></td>
<td><code>void</code></td>
</tr>
</tbody>
</table>
<h3 id="实用工具">实用工具</h3>
<h4 id="parselocation"><code>parseLocation</code></h4>
<pre><code class="language-typescript">parseLocation(location: RouteLocationRaw): { path: string; query?: Record&lt;string, string&gt; }
</code></pre>
<ul>
<li><strong>功能</strong>:将路由位置信息统一解析为路径和查询参数对象</li>
<li><strong>参数</strong>:
<ul>
<li><code>location</code>:支持字符串或对象格式的路由位置信息</li>
</ul>
</li>
<li><strong>返回</strong>:包含路径字符串和可选查询参数的对象</li>
</ul>
<h4 id="buildurl"><code>buildUrl</code></h4>
<pre><code class="language-typescript">buildUrl(path: string, query?: Record&lt;string, string | number | boolean&gt;): string
</code></pre>
<ul>
<li><strong>功能</strong>:根据路径和查询参数构建完整 URL</li>
<li><strong>参数</strong>:
<ul>
<li><code>path</code>:目标路径字符串</li>
<li><code>query</code>(可选):查询参数对象</li>
</ul>
</li>
<li><strong>返回</strong>:完整的 URL 字符串</li>
</ul>
<h4 id="getcurrentroute"><code>getCurrentRoute</code></h4>
<pre><code class="language-typescript">getCurrentRoute(currentPage: CurrentPage | null): Route | null
</code></pre>
<ul>
<li><strong>功能</strong>:获取当前页面的路由信息(支持多平台差异处理)</li>
<li><strong>参数</strong>:
<ul>
<li><code>currentPage</code>:当前页面实例(可为 null)</li>
</ul>
</li>
<li><strong>返回</strong>:当前路由对象或 null(获取失败时)</li>
</ul>
<h2 id="hooks">Hooks</h2>
<h3 id="usemxrouter-用于管理-router-组件实例并提供操作方法"><code>useMxRouter</code> 用于管理 <code>Router</code> 组件实例并提供操作方法</h3>
<p>注意:该 <code>Hook</code> 只支持 <code>vue3</code> 版本</p>
<pre><code class="language-vue">&lt;template&gt;
        &lt;mx-router @register="register"&gt;首页&lt;/mx-router&gt;
&lt;/template&gt;

&lt;script setup lang="ts"&gt;
import { useMxRouter } from '@meng-xi/uni-router'

const = useMxRouter({
        to: '/pages/index/index'
})
&lt;/script&gt;
</code></pre>
<h4 id="参数">参数</h4>
<table>
<thead>
<tr>
<th>属性</th>
<th>描述</th>
<th>类型</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>to</td>
<td>路由地址</td>
<td>RouterLinkProps</td>
<td>-</td>
</tr>
<tr>
<td>method</td>
<td>跳转方式</td>
<td>'push' | 'replace' | 'tab' | 'launch' | 'back' | 'exit'</td>
<td>'push'</td>
</tr>
<tr>
<td>delta</td>
<td>回退层数</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>animationType</td>
<td>窗口动画类型</td>
<td>UniApp.NavigateToOptions['animationType'] &amp; UniApp.NavigateBackOptions['animationType']</td>
<td>pop-in/out</td>
</tr>
<tr>
<td>animationDuration</td>
<td>动画持续时间</td>
<td>number</td>
<td>300</td>
</tr>
<tr>
<td>renderLink</td>
<td>是否给 navigator 组件加一层 a 标签控制 ssr 渲染</td>
<td>boolean</td>
<td>true</td>
</tr>
<tr>
<td>hoverClass</td>
<td>自定义悬停样式类名</td>
<td>string</td>
<td>'none'</td>
</tr>
<tr>
<td>hoverStopPropagation</td>
<td>指定是否阻止本节点的祖先节点出现点击态</td>
<td>boolean</td>
<td>false</td>
</tr>
<tr>
<td>hoverStartTime</td>
<td>按住后多久出现点击态,单位毫秒</td>
<td>number</td>
<td>50</td>
</tr>
<tr>
<td>hoverStayTime</td>
<td>手指松开后点击态保留时间,单位毫秒</td>
<td>number</td>
<td>600</td>
</tr>
<tr>
<td>target</td>
<td>在哪个小程序目标上发生跳转,值域 self/miniProgram</td>
<td>string</td>
<td>'self'</td>
</tr>
</tbody>
</table>
<h2 id="组件">组件</h2>
<h3 id="配置">配置</h3>
<p>建议使用 <code>easycom</code> 来简化组件的引入和注册</p>
<h4 id="npm">NPM</h4>
<pre><code class="language-json">// pages.json
{
        "easycom": {
                "custom": {
                        "^mx-(.*)": "@meng-xi/uni-router/components/$1/$1.vue"
                }
        }
}
</code></pre>
<h4 id="hbuilderx">HBuilderX</h4>
<p>如果你是通过插件市场导入到 <code>HBuilderX</code> 的,需要修改一下组件路径</p>
<pre><code class="language-json">// pages.json
{
        "easycom": {
                "custom": {
                        "^mx-(.*)": "@/js_sdk/PedroQue99-router/PedroQue99-router/components/$1/$1.vue"
                }
        }
}
</code></pre>
<h4 id="配置全局组件类型">配置全局组件类型</h4>
<p>在 <code>vscode</code> 中使用时,为了有组件的类型提示和自动填充,需要配置全局组件类型声明。</p>
<pre><code class="language-json">// tsconfig.json
{
        "compilerOptions": {
                "types": ["@meng-xi/uni-router/components/index"]
        }
}
</code></pre>
<p>如果是使用 <code>WebStorm</code>,可能需要在 main.ts 文件中导入 index.d.ts 文件。</p>
<pre><code class="language-typescript">// main.ts
import '@meng-xi/uni-router/components/index.d.ts'
</code></pre>
<h3 id="router-组件">Router 组件</h3>
<h4 id="介绍">介绍</h4>
<p><code>Router</code> 组件用于在应用中进行路由导航。它提供了一种声明式的方式来定义路由链接和导航行为。</p>
<h4 id="引入">引入</h4>
<pre><code class="language-typescript">import Router from '@meng-xi/uni-router/components/router/router.vue'
</code></pre>
<h4 id="基础用法">基础用法</h4>
<pre><code class="language-vue">&lt;template&gt;
        &lt;mx-router to="/pages/index/index"&gt;首页&lt;/mx-router&gt;
&lt;/template&gt;
</code></pre>
<h4 id="api">API</h4>
<h5 id="routerprops">RouterProps</h5>
<table>
<thead>
<tr>
<th>属性</th>
<th>描述</th>
<th>类型</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>to</td>
<td>路由地址</td>
<td>RouterLinkProps</td>
<td>-</td>
</tr>
<tr>
<td>method</td>
<td>跳转方式</td>
<td>'push' | 'replace' | 'tab' | 'launch' | 'back' | 'exit'</td>
<td>'push'</td>
</tr>
<tr>
<td>delta</td>
<td>回退层数</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>animationType</td>
<td>窗口动画类型</td>
<td>UniApp.NavigateToOptions['animationType'] &amp; UniApp.NavigateBackOptions['animationType']</td>
<td>pop-in/out</td>
</tr>
<tr>
<td>animationDuration</td>
<td>动画持续时间</td>
<td>number</td>
<td>300</td>
</tr>
<tr>
<td>renderLink</td>
<td>是否给 navigator 组件加一层 a 标签控制 ssr 渲染</td>
<td>boolean</td>
<td>true</td>
</tr>
<tr>
<td>hoverClass</td>
<td>自定义悬停样式类名</td>
<td>string</td>
<td>'none'</td>
</tr>
<tr>
<td>hoverStopPropagation</td>
<td>指定是否阻止本节点的祖先节点出现点击态</td>
<td>boolean</td>
<td>false</td>
</tr>
<tr>
<td>hoverStartTime</td>
<td>按住后多久出现点击态,单位毫秒</td>
<td>number</td>
<td>50</td>
</tr>
<tr>
<td>hoverStayTime</td>
<td>手指松开后点击态保留时间,单位毫秒</td>
<td>number</td>
<td>600</td>
</tr>
<tr>
<td>target</td>
<td>在哪个小程序目标上发生跳转,值域 self/miniProgram</td>
<td>string</td>
<td>'self'</td>
</tr>
</tbody>
</table>
<h5 id="routerslots">RouterSlots</h5>
<table>
<thead>
<tr>
<th>插槽</th>
<th>描述</th>
<th>属性</th>
</tr>
</thead>
<tbody>
<tr>
<td>default</td>
<td>自定义默认内容</td>
<td>-</td>
</tr>
</tbody>
</table>
<h2 id="错误处理">错误处理</h2>
<p><code>MxRouterError</code>类提供以下静态方法创建错误实例:</p>
<h4 id="navigationaborted"><code>navigationAborted</code></h4>
<pre><code class="language-typescript">static navigationAborted(): MxRouterError
</code></pre>
<ul>
<li><strong>用途</strong>:创建导航中止错误(用于前置守卫拦截场景)</li>
<li><strong>返回</strong>:导航中止错误实例</li>
</ul>
<h4 id="navigationredirect"><code>navigationRedirect</code></h4>
<pre><code class="language-typescript">static navigationRedirect(location: string | RouteLocationRaw): MxRouterError
</code></pre>
<ul>
<li><strong>用途</strong>:创建导航重定向错误(用于路由重定向场景)</li>
<li><strong>参数</strong>:
<ul>
<li><code>location</code>:重定向目标位置</li>
</ul>
</li>
<li><strong>返回</strong>:导航重定向错误实例</li>
</ul>
<h4 id="navigationfailed"><code>navigationFailed</code></h4>
<pre><code class="language-typescript">static navigationFailed(message: string): MxRouterError
</code></pre>
<ul>
<li><strong>用途</strong>:创建导航失败错误(用于导航异常场景)</li>
<li><strong>参数</strong>:
<ul>
<li><code>message</code>:错误描述信息</li>
</ul>
</li>
<li><strong>返回</strong>:导航失败错误实例</li>
</ul>
<h4 id="invalidmethod"><code>invalidMethod</code></h4>
<pre><code class="language-typescript">static invalidMethod(method: string): MxRouterError
</code></pre>
<ul>
<li><strong>用途</strong>:创建无效方法错误(用于调用非法导航方法场景)</li>
<li><strong>参数</strong>:
<ul>
<li><code>method</code>:无效的方法名称</li>
</ul>
</li>
<li><strong>返回</strong>:无效方法错误实例</li>
</ul><br><br>
来源:https://www.cnblogs.com/PedroQue99/p/19004633
頁: [1]
查看完整版本: @meng-xi/uni-router