├── .npmignore ├── .husky ├── commit-msg └── pre-commit ├── docs ├── public │ ├── logo.png │ ├── favicon.ico │ ├── alipayQrcode.jpg │ └── weixinQrcode.jpg ├── .vitepress │ ├── theme │ │ ├── components │ │ │ ├── layout.vue │ │ │ ├── NavBarTitleAfter.vue │ │ │ ├── SvgImage.vue │ │ │ ├── AsideSponsors.vue │ │ │ ├── HomeSponsors.vue │ │ │ └── frame.vue │ │ ├── composables │ │ │ └── sponsor.ts │ │ ├── styles │ │ │ ├── scrollbar.css │ │ │ ├── custom.css │ │ │ └── vars.css │ │ └── index.ts │ └── config.ts ├── guide │ ├── common-problems.md │ ├── introduction.md │ ├── api.md │ ├── installation.md │ ├── usage.md │ ├── quick-use.md │ └── changelog.md ├── reward │ ├── donor.md │ └── reward.md └── index.md ├── .gitee ├── ISSUE_TEMPLATE.zh-CN.md └── PULL_REQUEST_TEMPLATE.zh-CN.md ├── .eslintignore ├── .prettierrc ├── commitlint.config.js ├── .gitignore ├── tsconfig.types.json ├── babel.config.js ├── src ├── symbols │ └── index.ts ├── core │ └── index.ts ├── utils │ └── index.ts ├── index.ts ├── interfaces │ └── index.ts └── router │ └── index.ts ├── .github ├── workflows │ ├── npm-publish.yml │ ├── deploy.yml │ └── release.yml └── ISSUE_TEMPLATE │ ├── 2-feature-request.yml │ └── 1-bug-report.yml ├── LICENSE ├── .vscode └── settings.json ├── tsconfig.json ├── .eslintrc.js ├── .versionrc ├── .git-cz.json ├── typesCopy.js ├── README.md ├── package.json ├── rollup.config.js └── CHANGELOG.md /.npmignore: -------------------------------------------------------------------------------- 1 | changelog.config.js -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged --allow-empty $1 5 | -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moonofweisheng/uni-mini-router/HEAD/docs/public/logo.png -------------------------------------------------------------------------------- /docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moonofweisheng/uni-mini-router/HEAD/docs/public/favicon.ico -------------------------------------------------------------------------------- /docs/public/alipayQrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moonofweisheng/uni-mini-router/HEAD/docs/public/alipayQrcode.jpg -------------------------------------------------------------------------------- /docs/public/weixinQrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moonofweisheng/uni-mini-router/HEAD/docs/public/weixinQrcode.jpg -------------------------------------------------------------------------------- /.gitee/ISSUE_TEMPLATE.zh-CN.md: -------------------------------------------------------------------------------- 1 | ### 该问题是怎么引起的? 2 | 3 | 4 | 5 | ### 重现步骤 6 | 7 | 8 | 9 | ### 报错信息 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | babel.config.js 3 | changelog.config.js 4 | commitlint.config.js 5 | rollup.config.js 6 | typesCopy.js 7 | styleCopy.js 8 | src/iconfont/* -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/layout.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "none", 6 | "bracketSpacing": true, 7 | "requirePragma": false, 8 | "proseWrap": "preserve", 9 | "arrowParens": "always", 10 | "htmlWhitespaceSensitivity": "ignore", 11 | "endOfLine": "lf" 12 | } -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/NavBarTitleAfter.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 徐庆凯 3 | * @Date: 2022-11-18 18:32:34 4 | * @LastEditTime: 2023-03-10 10:28:31 5 | * @LastEditors: 徐庆凯 6 | * @Description: 7 | * @FilePath: \uni-read-pages-vite\commitlint.config.js 8 | * 记得注释 9 | */ 10 | // eslint-disable-next-line no-undef 11 | module.exports = { 12 | extends: ['@commitlint/config-conventional'] 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /lib 4 | unpackage 5 | dist/ 6 | /docs/.vitepress/cache 7 | .vitepress/cache 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | -------------------------------------------------------------------------------- /tsconfig.types.json: -------------------------------------------------------------------------------- 1 | { 2 | // 继承 tsconfig.json 中的通用配置 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "removeComments": false, 6 | "skipLibCheck": true, 7 | "declaration": true /* 生成相应的 '.d.ts' file. */, 8 | "declarationDir": "./lib/types" /* 类型声明文件输出目录 */, 9 | "emitDeclarationOnly": true /* 只生成声明文件,不生成 js 文件*/, 10 | "rootDir": "./src" /* 指定输出文件目录(用于输出),用于控制输出目录结构 */ 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef 2 | module.exports = { 3 | presets: [ 4 | [ 5 | '@babel/preset-env', 6 | { 7 | /* Babel 会在 Rollup 有机会做处理之前,将我们的模块转成 CommonJS,导致 Rollup 的一些处理失败 */ 8 | modules: false 9 | } 10 | ] 11 | ], 12 | plugins: [ 13 | [ 14 | // 与 babelHelpers: 'runtime' 配合使用 15 | '@babel/plugin-transform-runtime' 16 | ] 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/SvgImage.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 23 | -------------------------------------------------------------------------------- /docs/guide/common-problems.md: -------------------------------------------------------------------------------- 1 | # 常见问题FAQ 2 | 3 | 本节介绍在开发过程当中遇到的部分 **常见问题** 以及 **解决办法** 4 | 5 | ## nvue支持吗? 6 | 7 | 目前没有支持。 8 | 9 | 10 | ## Uni Mini Router的目标? 11 | 12 | `Uni Mini Router`目标是基于小程序平台,将`uni-app`路由相关的API对齐`Vue Router`,而并非提供完全的`Vue Router`。 13 | 14 | 15 | ## 导航守卫的局限? 16 | - 首屏无法触发前置导航守卫:建议有相关需求的用户,自行创建空白首屏页面进行相关业务逻辑判断确认后,再进行后续的路由跳转。 17 | - 无法拦截Tabbar页面跳转:Tabbar 页面跳转未使用路由API,故无法拦截。 18 | - 非API返回:非API返回跳转未使用路由API,故无法拦截。 19 | 20 | 21 | ## 关于我们 22 | 23 | **如果您的问题不在上述列表中或您有更好的建议,请联系我们 [Moonofweisheng](https://github.com/Moonofweisheng/uni-mini-router)** 24 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/AsideSponsors.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /src/symbols/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: weisheng 3 | * @Date: 2023-03-13 17:01:30 4 | * @LastEditTime: 2023-04-26 21:51:51 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: \uni-mini-router\src\symbols\index.ts 8 | * 记得注释 9 | */ 10 | import type { InjectionKey, Ref } from 'vue' 11 | import type { Route, Router } from '../interfaces' 12 | 13 | /** 14 | * useRouter 用到的key 15 | * 16 | * @internal 17 | */ 18 | export const routerKey = Symbol('__ROUTER__') as InjectionKey 19 | 20 | /** 21 | * useRoute 用到的key 22 | * 23 | * @internal 24 | */ 25 | export const routeKey = Symbol('__ROUTE__') as InjectionKey> 26 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/composables/sponsor.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: weisheng 3 | * @Date: 2023-08-01 11:12:05 4 | * @LastEditTime: 2023-08-01 21:16:30 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: \wot-design-uni\docs\.vitepress\theme\composables\sponsor.ts 8 | * 记得注释 9 | */ 10 | import { ref, onMounted } from 'vue' 11 | 12 | 13 | const data = ref() 14 | 15 | export function useSponsor() { 16 | onMounted(async () => { 17 | if (data.value) { 18 | return 19 | } 20 | const result = await fetch('https://fant-mini-plus.top/sponsors/wot-design-uni.json') 21 | const json = await result.json() 22 | data.value = json 23 | }) 24 | 25 | return { 26 | data, 27 | } 28 | } 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to npm 2 | on: 3 | push: 4 | tags: 5 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout code 12 | uses: actions/checkout@v2 13 | 14 | - name: Setup Node.js 15 | uses: actions/setup-node@v2 16 | with: 17 | node-version: '16.x' 18 | registry-url: https://registry.npmjs.org 19 | 20 | - name: Install Dependencies 21 | run: yarn 22 | 23 | - name: Run Build 24 | run: yarn build 25 | 26 | - name: Publish Package 27 | run: npm publish 28 | env: 29 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} -------------------------------------------------------------------------------- /docs/reward/donor.md: -------------------------------------------------------------------------------- 1 | # 榜上有名 2 | 3 | 感谢各位捐赠者对本项目的支持,以下排名不分先后,按时间顺序排列。 4 | 5 | :::tip 6 | 捐赠后,请发送邮件到1780903673@qq.com或者通过github、微信群等社交平台告知要展示的捐赠者名称、留言、链接 (链接可以是您的博客、github、个人网站、公司产品等) 7 | ::: 8 | 9 | ## 捐赠榜单 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
捐赠者留言链接
{{donor.name}}{{donor.message}}{{donor.link}}
28 | 29 | 30 | :beers::beers::beers: 再次感谢各位捐赠者的支持,也欢迎大家提出自己的意见和建议。:beers::beers::beers: 31 | 32 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Uni Mini Router 5 | titleTemplate: 一个基于vue3和Typescript的轻量级uni-app路由库 6 | 7 | hero: 8 | name: Uni Mini Router 9 | text: 10 | tagline: 一个基于vue3和Typescript的轻量级uni-app路由库 11 | image: 12 | src: /logo.png 13 | alt: Wot Design 14 | actions: 15 | - theme: brand 16 | text: 快速上手 17 | link: /guide/installation 18 | - theme: alt 19 | text: 在Github上查看 20 | link: https://github.com/Moonofweisheng/uni-mini-router 21 | - theme: alt 22 | text: 捐赠作者 23 | link: /reward/reward 24 | 25 | features: 26 | - icon: 🚀 27 | title: 多平台覆盖 28 | details: 支持 APP、H5、微信小程序 等平台。 29 | - icon: 🚀 30 | title: 支持导航守卫 31 | details: 支持全局前置导航守卫 beforeEach 和全局后置导航守卫 afterEach。 32 | - icon: 💪 33 | title: 支持 TypeScript 34 | details: 使用 Typescript 构建,提供良好的组件类型系统。 35 | --- 36 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles/scrollbar.css: -------------------------------------------------------------------------------- 1 | .VPSidebar{ 2 | overflow: hidden !important; 3 | } 4 | .VPSidebar:hover{ 5 | overflow-y: auto !important; 6 | } 7 | 8 | * { 9 | scrollbar-color: var(--el-scrollbar-bg-color) var(--el-fill-color-light); 10 | } 11 | 12 | ::-webkit-scrollbar { 13 | width: 6px; 14 | } 15 | 16 | ::-webkit-scrollbar:horizontal { 17 | height: 6px 18 | } 19 | 20 | ::-webkit-scrollbar-track { 21 | border-radius: 10px; 22 | } 23 | 24 | ::-webkit-scrollbar-thumb { 25 | background-color: rgba(0, 0, 0, 0.2); 26 | border-radius: 10px; 27 | transition: all 0.2s ease-in-out; 28 | } 29 | 30 | ::-webkit-scrollbar-thumb:hover { 31 | cursor: pointer; 32 | background-color: rgba(0, 0, 0, 0.3); 33 | } 34 | 35 | 36 | .dark::-webkit-scrollbar-thumb { 37 | background-color: rgba(255, 255, 255, 0.2); 38 | } 39 | 40 | .dark::-webkit-scrollbar-thumb:hover { 41 | background-color: rgba(255, 255, 255, 0.4); 42 | } -------------------------------------------------------------------------------- /.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md: -------------------------------------------------------------------------------- 1 | ### 一、内容说明(相关的Issue) 2 | 3 | 4 | 5 | ### 二、建议测试周期和提测地址 6 | 建议测试完成时间:xxxx.xx.xx 7 | 投产上线时间:xxxx.xx.xx 8 | 提测地址:CI环境/压测环境 9 | 测试账号: 10 | 11 | ### 三、变更内容 12 | * 3.1 关联PR列表 13 | 14 | * 3.2 数据库和部署说明 15 | 1. 常规更新 16 | 2. 重启unicorn 17 | 3. 重启sidekiq 18 | 4. 迁移任务:是否有迁移任务,没有写 "无" 19 | 5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无" 20 | 21 | * 3.4 其他技术优化内容(做了什么,变更了什么) 22 | - 重构了 xxxx 代码 23 | - xxxx 算法优化 24 | 25 | 26 | * 3.5 废弃通知(什么字段、方法弃用?) 27 | 28 | 29 | 30 | * 3.6 后向不兼容变更(是否有无法向后兼容的变更?) 31 | 32 | 33 | 34 | ### 四、研发自测点(自测哪些?冒烟用例全部自测?) 35 | 自测测试结论: 36 | 37 | 38 | ### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方) 39 | 检查点: 40 | 41 | | 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 | 42 | |------|------------|----------|---------------| 43 | | xxx | 否 | 需要 | 不需要 | 44 | | | | | | 45 | 46 | 接口测试: 47 | 48 | 性能测试: 49 | 50 | 并发测试: 51 | 52 | 其他: 53 | 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-feature-request.yml: -------------------------------------------------------------------------------- 1 | name: 向 uni-mini-router 提出新功能需求 2 | description: 创建一个 Issue 描述一下你的功能需求。 3 | title: "[新功能需求] 请在此填写标题" 4 | labels: ["feature: need confirm"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | 在提交功能需求前,请注意: 10 | 11 | - 确认这是一个通用功能,并且无法通过现有的 API 实现。 12 | - 尝试在 [Issue](https://github.com/Moonofweisheng/uni-mini-router/issues)列表中搜索,并且没有发现同样的需求。 13 | - 可以先到 [Discussions 讨论区](https://github.com/Moonofweisheng/uni-mini-router/discussions) 发帖,讨论一下需求是否合理。 14 | 15 | - type: textarea 16 | id: description 17 | attributes: 18 | label: 这个功能解决了什么问题? 19 | description: 请尽可能详细地说明这个功能的使用场景。 20 | validations: 21 | required: true 22 | 23 | - type: textarea 24 | id: api 25 | attributes: 26 | label: 你期望的 API 是什么样子的? 27 | description: 描述一下这个新功能的 API,并提供一些代码示例。 28 | placeholder: | 29 | ```xml 30 | router.interesting() 31 | ``` 32 | validations: 33 | required: true -------------------------------------------------------------------------------- /docs/reward/reward.md: -------------------------------------------------------------------------------- 1 | # 捐赠作者 2 | 3 | 如果您认为本项目对你的工作起到了帮助,可以通过以下方式捐助组件库的研发工作,使本项目持续发展下去,捐赠后你的头像、昵称和主页将会被展示在 `Uni Mini Router` 文档的捐赠榜单上。 4 | 5 | :::tip 6 | 捐赠后,可以发送邮件到1780903673@qq.com或者通过github、微信群等社交平台告知要展示的捐赠者名称、留言、链接 (链接可以是您的博客、github、个人网站、公司产品等) 7 | ::: 8 | 9 | 10 | 11 | ### 爱发电捐赠 12 | 13 | https://afdian.net/a/weisheng233 14 | 15 | 16 | ### 扫码捐赠 17 | 18 | 19 |
20 | 21 |
微信
22 |
23 | 24 |
25 | 26 |
支付宝
27 |
28 | 29 | -------------------------------------------------------------------------------- /docs/guide/introduction.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 3 | `uni-mini-router`是一个基于`vue3`和`uni-app`框架的轻量级路由库,它提供了类似`Vue Router`的API和功能,可以帮助开发者实现在uni-app中进行路由跳转、传参、拦截等常用操作。 4 | 5 | `uni-mini-router`支持多种跳转方式,包括普通跳转、重定向、切换TabBar页面等。它也提供了一些高级特性,如路由拦截、编程式导航等。 6 | 7 | 总之,如果你在`uni-app`开发过程中需要使用到路由功能,可以考虑使用`uni-mini-router`来简化你的开发工作。 8 | 9 | ## 快速上手 10 | 11 | 请查看[快速上手](/guide/installation.html)文档。 12 | 13 | ## ✨ 特性 14 | 15 | - 🚀 支持 APP、H5、微信小程序 等平台. 16 | - 💪 支持全局前置导航守卫 beforeEach 和全局后置导航守卫 afterEach. 17 | - 💪 使用 Typescript 构建,提供良好的组件类型系统. 18 | 19 | ## 链接 20 | 21 | * [意见反馈](https://github.com/Moonofweisheng/uni-mini-router/issues) 22 | * [更新日志](/guide/changelog) 23 | * [常见问题](/guide/common-problems) 24 | * [Discussions 讨论区](https://github.com/Moonofweisheng/uni-mini-router/discussions) 25 | * [QQ 群](https://qm.qq.com/cgi-bin/qm/qr?k=O1Z3pal6StL39qHtABqR54Tb56igr90O&jump_from=webapi&authKey=MtVWfi/EQbT03wW7tKXv4bmyKYHBHtzI8VewlzSsOdxFjN0wbgNy17np9Z9yC4Z8) 26 | * [高颜值vue3组件库 Wot Design Uni](https://wot-design-uni.netlify.app/) 27 | * [整合uni-mini-router的起手项目](https://github.com/Moonofweisheng/wot-starter) 28 | 29 | ## 开源协议 30 | 31 | 本项目遵循 MIT 协议。 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 徐庆凯 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: weisheng 3 | * @Date: 2023-07-27 12:36:30 4 | * @LastEditTime: 2023-10-22 21:51:22 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: \uni-mini-router\docs\.vitepress\theme\index.ts 8 | * 记得注释 9 | */ 10 | import { h } from 'vue' 11 | import Theme from 'vitepress/theme' 12 | import './styles/vars.css' 13 | import './styles/custom.css' 14 | import './styles/scrollbar.css' 15 | import ElementPlus from 'element-plus' 16 | import 'element-plus/dist/index.css' 17 | 18 | // import HomeSponsors from './components/HomeSponsors.vue' 19 | import NavBarTitleAfter from './components/NavBarTitleAfter.vue' 20 | import SvgImage from './components/SvgImage.vue' 21 | import frame from './components/frame.vue' 22 | 23 | 24 | 25 | export default { 26 | ...Theme, 27 | Layout() { 28 | return h(Theme.Layout, null, { 29 | // 'home-features-after': () => h(HomeSponsors), 30 | 'nav-bar-title-after': () => h(NavBarTitleAfter), 31 | }) 32 | }, 33 | enhanceApp({ app }) { 34 | app.use(ElementPlus) 35 | app.component('SvgImage', SvgImage) 36 | app.component('frame', frame) 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.settings.useSplitJSON": true, 3 | // vscode默认启用了根据文件类型自动设置tabsize的选项 4 | "editor.detectIndentation": false, 5 | // 重新设定tabsize 6 | "editor.tabSize": 2, 7 | // #每次保存的时候自动格式化 8 | // "editor.formatOnSave": true, 9 | // #每次保存的时候将代码按eslint格式进行修复 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll.eslint": "explicit" 12 | }, 13 | // 添加 vue 支持 14 | "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"], 15 | // #去掉代码结尾的分号 16 | "prettier.semi": true, 17 | // #使用单引号替代双引号 18 | "prettier.singleQuote": true, 19 | // #让函数(名)和后面的括号之间加个空格 20 | "javascript.format.insertSpaceBeforeFunctionParenthesis": true, 21 | "typescript.format.insertSpaceBeforeFunctionParenthesis": true, 22 | // #这个按用户自身习惯选择 23 | "vetur.format.defaultFormatter.html": "js-beautify-html", 24 | // #让vue中的js按编辑器自带的ts格式进行格式化 25 | "vetur.format.defaultFormatter.js": "vscode-typescript", 26 | "vetur.format.options.tabSize": 2, 27 | "vetur.format.defaultFormatterOptions": { 28 | "js-beautify-html": { 29 | "wrap_line_length": 120, 30 | "wrap_attributes": true, 31 | "end_with_newline": true 32 | // #vue组件中html代码格式化样式 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* 基础选项 */ 4 | "target": "esnext" /* 指定 ECMAScript 目标版本:'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, 5 | "module": "esnext" /* 输出的代码使用什么方式进行模块化: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 6 | "lib": [ /* 指定引用的标准库 */ 7 | "esnext", 8 | "dom", 9 | "dom.iterable", 10 | "esnext.String" 11 | ], 12 | "allowJs": true /* 允许编译 js 文件 */, 13 | "allowSyntheticDefaultImports": true, 14 | "removeComments": true /* 输出不包含注释 */, 15 | /* 严格类型检查选项 */ 16 | "strict": true /* 启用所有严格类型检查选项 */, 17 | "noImplicitAny": true /* 检查隐含 any 类型的表达式和声明 */, 18 | "strictNullChecks": false /* 严格空检查. */, 19 | /* 额外检查 */ 20 | "noUnusedLocals": true /* 检查无用的变量. */, 21 | /* Module Resolution Options */ 22 | "moduleResolution": "node" /* 指定模块查找策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) */, 23 | "baseUrl": "./" /* 查找模块的基础目录 */, 24 | "paths": { 25 | "@/*": [ 26 | "src/*" 27 | ] 28 | } /* 记录 baseUrl 的模块路径查找别名 */, 29 | "types": [ 30 | "@types/node", 31 | "@dcloudio/types" 32 | ] /* 类型声明文件 */ 33 | }, 34 | "include": [ /* 指定编译处理的文件列表 */ 35 | "src/*.ts", 36 | ] 37 | } -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line 2 | module.exports = { 3 | env: { 4 | browser: true, 5 | es2021: true 6 | }, 7 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], 8 | overrides: [], 9 | parser: '@typescript-eslint/parser', 10 | parserOptions: { 11 | ecmaVersion: 'latest', 12 | sourceType: 'module' 13 | }, 14 | plugins: ['@typescript-eslint'], 15 | rules: { 16 | 'prettier/prettier': 'error', 17 | 'linebreak-style': ['error', 'unix'], 18 | quotes: ['error', 'single'], 19 | semi: ['error', 'never'], 20 | 'no-multiple-empty-lines': [ 21 | 2, 22 | { 23 | max: 1, 24 | maxBOF: 0 25 | } 26 | ], 27 | 'space-before-function-paren': 0, 28 | '@typescript-eslint/no-empty-function': 'off', 29 | 'no-inner-declarations': 'off', 30 | '@typescript-eslint/no-explicit-any': 'off', 31 | '@typescript-eslint/no-use-before-define': 'off', 32 | '@typescript-eslint/no-inferrable-types': 0, 33 | '@typescript-eslint/no-unused-vars': 'off', 34 | '@typescript-eslint/no-non-null-assertion': 'off', 35 | '@typescript-eslint/no-var-requires': 'off', 36 | '@typescript-eslint/no-namespace': 'off', 37 | '@typescript-eslint/no-this-alias': 'off' 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/guide/api.md: -------------------------------------------------------------------------------- 1 | # API 文档 2 | 3 | ## createRouter 4 | 5 | ▸ createRouter(options): `Router` 6 | 7 | 创建一个可以被 Vue 应用使用的 Router 实例。 8 | 9 | ### 参数 10 | | 名称 | 类型 |描述| 11 | | --- | --- | -- | 12 | | options | `RouterOptions` |`RouterOptions`| 13 | 14 | ### 返回值 15 | `Router` 16 | 17 | 18 | ## useRouter 19 | 20 | ▸ useRouter(): `Router` 21 | 22 | 返回路由器实例。相当于在模板中使用 $Router。 23 | 24 | >不可以脱离 Vue 上下文使用 25 | 26 | ### 返回值 27 | 28 | `Router` 29 | 30 | 31 | 32 | ## useRoute 33 | 34 | ▸ useRoute(): `Route` 35 | 36 | 返回当前的路由地址信息。相当于在模板中使用 $Route。 37 | 38 | >不可以脱离 Vue 上下文使用,且只能在页面`mount`之后才可与使用。当使用场景为外部链接跳转进入或H5页面刷新时,默认从当前链接中取得query参数并放在`Route`的`query`字段中,这种场景建议走`onLoad`声明周期获取参数。 39 | 40 | ### 返回值 41 | 42 | `Route` 43 | 44 | ## Router实例方法 45 | 46 | ### push方法 47 | 48 | ▸ router.push(target:RouteLocationRaw): void 49 | 50 | 保留当前页面,跳转到应用内的某个页面,相当于使用 `uni.navigateTo(OBJECT)`。 51 | 52 | 53 | ### pushTab方法 54 | 55 | ▸ router.pushTab(target:RouteLocationRaw): void 56 | 57 | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面,相当于使用 `uni.switchTab(OBJECT)`。 58 | 59 | ### replace方法 60 | 61 | ▸ router.replace(target:RouteLocationRaw): void 62 | 63 | 关闭当前页面,跳转到应用内的某个页面,相当于使用 `uni.redirectTo(OBJECT)`。 64 | 65 | ### replaceAll方法 66 | 67 | ▸ router.replaceAll(target:RouteLocationRaw): void 68 | 69 | 关闭所有页面,打开到应用内的某个页面,相当于使用 `uni.reLaunch(OBJECT)`。 70 | 71 | ### back方法 72 | 73 | ▸ router.back(level?: number): void 74 | 75 | 关闭当前页面,返回上一页面或多级页面,相当于使用 `uni.navigateBack(OBJECT)`。 76 | 77 | -------------------------------------------------------------------------------- /.versionrc: -------------------------------------------------------------------------------- 1 | { 2 | "header": "# 更新日志 \n\n", 3 | "types": [{ 4 | "type": "feat", 5 | "section": "✨ Features | 新功能", 6 | "hidden": false 7 | }, 8 | { 9 | "type": "fix", 10 | "section": "🐛 Bug Fixes | Bug 修复", 11 | "hidden": false 12 | }, 13 | { 14 | "type": "init", 15 | "section": "🎉 Init | 初始化", 16 | "hidden": true 17 | }, 18 | { 19 | "type": "docs", 20 | "section": "✏️ Documentation | 文档", 21 | "hidden": false 22 | }, 23 | { 24 | "type": "style", 25 | "section": "💄 Styles | 风格", 26 | "hidden": true 27 | }, 28 | { 29 | "type": "refactor", 30 | "section": "♻️ Code Refactoring | 代码重构", 31 | "hidden": true 32 | }, 33 | { 34 | "type": "perf", 35 | "section": "⚡ Performance Improvements | 性能优化", 36 | "hidden": true 37 | }, 38 | { 39 | "type": "test", 40 | "section": "✅ Tests | 测试", 41 | "hidden": true 42 | }, 43 | { 44 | "type": "revert", 45 | "section": "⏪ Revert | 回退", 46 | "hidden": true 47 | }, 48 | { 49 | "type": "build", 50 | "section": "📦‍ Build System | 打包构建", 51 | "hidden": true 52 | }, 53 | { 54 | "type": "chore", 55 | "section": "🚀 Chore | 构建/工程依赖/工具", 56 | "hidden": true 57 | }, 58 | { 59 | "type": "ci", 60 | "section": "👷 Continuous Integration | CI 配置", 61 | "hidden": true 62 | } 63 | ] 64 | } -------------------------------------------------------------------------------- /src/core/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 徐庆凯 3 | * @Date: 2023-03-13 19:02:05 4 | * @LastEditTime: 2023-04-27 13:16:26 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: \uni-mini-router\src\core\index.ts 8 | * 记得注释 9 | */ 10 | import type { Route, Router } from '../interfaces' 11 | import { inject, reactive, watch } from 'vue' 12 | import { routeKey, routerKey } from '../symbols' 13 | /** 14 | * 返回router实例,在template的仍然可以使用$Router方法 15 | */ 16 | export function useRouter(): Router { 17 | const router = inject(routerKey) 18 | if (router) { 19 | return router 20 | } else { 21 | throw new Error('useRouter 只可以在 Vue 上下文中使用,请确保你已经正确地注册了 "uni-mini-router" 并且当前正处于 Vue 上下文中') 22 | // throw new Error( 23 | // 'Error: useRouter can only be used within a Vue component context. Make sure you have registered the "uni-mini-router" correctly and it is being used inside a Vue component' 24 | // ) 25 | } 26 | } 27 | 28 | /** 29 | * 返回当前页面路由信息route,在template的仍然可以使用$Route方法 30 | */ 31 | export function useRoute(): Route { 32 | const currentRoute = inject(routeKey) 33 | if (currentRoute) { 34 | const route = reactive(currentRoute.value) 35 | watch(currentRoute, (to) => { 36 | Object.assign(route, to) 37 | }) 38 | return route 39 | } else { 40 | throw new Error('useRoute 只可以在 Vue 上下文中使用,请确保你已经正确地注册了 "uni-mini-router" 并且当前正处于 Vue 上下文中') 41 | // throw new Error( 42 | // 'Error: useRoute can only be used within a Vue component context. Make sure you have registered the "uni-mini-router" correctly and it is being used inside a Vue component' 43 | // ) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a VitePress site to GitHub Pages 2 | # 3 | name: Deploy VitePress site to Pages 4 | 5 | on: 6 | push: 7 | tags: 8 | - '*' 9 | 10 | workflow_dispatch: 11 | 12 | jobs: 13 | deploy-and-sync: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 🛎️ 17 | uses: actions/checkout@v4 18 | with: 19 | ref: 'master' 20 | 21 | - name: Install yarn 22 | run: corepack enable 23 | 24 | - uses: actions/setup-node@v3 25 | with: 26 | node-version: '18' 27 | cache: 'yarn' 28 | 29 | - name: Install dependencies 30 | run: yarn install 31 | 32 | - name: Build Site 33 | run: npm run docs:build 34 | 35 | - name: Deploy for Gitee 🚀 36 | uses: JamesIves/github-pages-deploy-action@v4.4.1 37 | with: 38 | branch: gh-pages 39 | folder: docs/.vitepress/dist 40 | # enable single-commit to reduce the repo size 41 | single-commit: true 42 | clean: true 43 | 44 | - name: Sync to Gitee 45 | uses: wearerequired/git-mirror-action@v1.2.0 46 | env: 47 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }} 48 | with: 49 | source-repo: git@github.com:Moonofweisheng/uni-mini-router.git 50 | destination-repo: git@gitee.com:Moonofweisheng/uni-mini-router.git 51 | 52 | - name: Build Gitee Pages 53 | uses: yanglbme/gitee-pages-action@main 54 | with: 55 | gitee-username: Moonofweisheng 56 | gitee-password: ${{ secrets.GITEE_PASSWORD }} 57 | gitee-repo: Moonofweisheng/uni-mini-router 58 | branch: gh-pages -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/HomeSponsors.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 33 | 34 | 71 | -------------------------------------------------------------------------------- /.git-cz.json: -------------------------------------------------------------------------------- 1 | { 2 | "disableEmoji": false, 3 | "list": ["test", "feat", "fix", "chore", "docs", "refactor", "style", "ci", "perf", "release", "revert", "build"], 4 | "maxMessageLength": 64, 5 | "minMessageLength": 3, 6 | "questions": ["type", "scope", "subject", "body", "breaking", "issues", "lerna"], 7 | "scopes": [], 8 | "types": { 9 | "chore": { 10 | "description": "Chore | 构建/工程依赖/工具", 11 | "emoji": "🚀", 12 | "value": "chore" 13 | }, 14 | "ci": { 15 | "description": "Continuous Integration | CI 配置", 16 | "emoji": "👷", 17 | "value": "ci" 18 | }, 19 | "docs": { 20 | "description": "Documentation | 文档", 21 | "emoji": "✏️ ", 22 | "value": "docs" 23 | }, 24 | "feat": { 25 | "description": "Features | 新功能", 26 | "emoji": "✨", 27 | "value": "feat" 28 | }, 29 | "fix": { 30 | "description": "Bug Fixes | Bug 修复", 31 | "emoji": "🐛", 32 | "value": "fix" 33 | }, 34 | "perf": { 35 | "description": "Performance Improvements | 性能优化", 36 | "emoji": "⚡", 37 | "value": "perf" 38 | }, 39 | "refactor": { 40 | "description": "Code Refactoring | 代码重构", 41 | "emoji": "♻️ ", 42 | "value": "refactor" 43 | }, 44 | "release": { 45 | "description": "Create a release commit | 发版提交", 46 | "emoji": "🏹", 47 | "value": "release" 48 | }, 49 | "style": { 50 | "description": "Styles | 风格", 51 | "emoji": "💄", 52 | "value": "style" 53 | }, 54 | "revert": { 55 | "description": "Revert | 回退", 56 | "emoji": "⏪", 57 | "value": "revert" 58 | }, 59 | "build": { 60 | "description": "Build System | 打包构建", 61 | "emoji": "📦", 62 | "value": "build" 63 | }, 64 | "test": { 65 | "description": "Tests | 测试", 66 | "emoji": "✅", 67 | "value": "test" 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /typesCopy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 徐庆凯 3 | * @Date: 2022-12-02 14:34:18 4 | * @LastEditTime: 2023-03-10 11:41:26 5 | * @LastEditors: 徐庆凯 6 | * @Description: .d.ts移动到制品 7 | * @FilePath: \uni-read-pages-vite\typesCopy.js 8 | * 记得注释 9 | */ 10 | const fs = require("fs"); 11 | const path = require("path"); 12 | const srcRoot = path.join(__dirname, './src') 13 | const targetSrcRoot = path.join(__dirname, "./lib"); 14 | const componentRoot = path.join(__dirname, "./src"); 15 | const componentNames = fs 16 | // 获取所有文件夹及文件 17 | .readdirSync(`${componentRoot}`, { 18 | withFileTypes: true 19 | }) 20 | // 筛选出所有文件夹 21 | .filter((p) => { 22 | return p.isDirectory() && fs.existsSync(`${componentRoot}/${p.name}/index.ts`) 23 | }) 24 | // 数据预处理 25 | .map((p) => { 26 | return { 27 | path: `${p.name}/index`, 28 | name: p.name, 29 | } 30 | }) 31 | .concat({ 32 | path: "index", 33 | name: "index" 34 | }) 35 | 36 | const copy = () => { 37 | componentNames.forEach((component) => { 38 | let sourcePath = `${srcRoot}/${component.path.replace(/index/g,'')}/index.d.ts`.replace(/src/g, 'lib/types').replace(/\/\//g, '/') 39 | let targetPath = sourcePath.replace(/types\//g, '') 40 | try { 41 | fs.copyFileSync(sourcePath, targetPath); 42 | } catch (e) { 43 | console.log(e, "复制失败"); 44 | } 45 | }); 46 | } 47 | 48 | const deleteTarget = function (tarPath) { 49 | if (!fs.existsSync(tarPath)) { 50 | return 51 | } 52 | let files = fs.readdirSync(tarPath) 53 | files.forEach(function (filename) { 54 | const filedir = path.join(tarPath, filename) 55 | let stats = fs.statSync(filedir) 56 | const isFile = stats.isFile() 57 | if (isFile) { 58 | // 复制文件 59 | fs.rmSync(filedir) 60 | } else { 61 | deleteTarget(filedir) // 递归 62 | } 63 | }) 64 | fs.rmdirSync(tarPath) 65 | } 66 | 67 | copy() 68 | deleteTarget(path.join(targetSrcRoot, "./types")) -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 向 Uni Mini Router 反馈 Bug 2 | description: 创建一个 Issue 描述你遇到的问题。 3 | title: "[Bug 上报] 请在此填写标题" 4 | labels: ["🐞bug: need confirm"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | 在向我们提交 Bug 报告前,请优先使用以下方式尝试解决问题: 10 | - 尝试在 [Issue](https://github.com/Moonofweisheng/uni-mini-router/issues) 列表中搜索相同问题 11 | - 如果不是反馈 Bug,请到 [Discussions 讨论区](https://github.com/Moonofweisheng/uni-mini-router/discussions) 发帖。 12 | 13 | - type: input 14 | id: version 15 | attributes: 16 | label: uni-mini-router 版本号 17 | description: 你正在使用的组件库版本号(请填写 uni-mini-router/package.json 里实际安装的版本) 18 | placeholder: 例如:0.1.1 19 | validations: 20 | required: true 21 | 22 | - type: dropdown 23 | id: platform 24 | attributes: 25 | label: 平台 26 | multiple: true 27 | description: 选择对应的平台 28 | options: 29 | - h5 30 | - 微信小程序 31 | - 支付宝小程序 32 | - APP 33 | - 钉钉小程序 34 | - 其他小程序 35 | validations: 36 | required: true 37 | 38 | - type: input 39 | id: reproduce 40 | attributes: 41 | label: 重现链接 42 | description: | 43 | 请提供一个尽可能简单的 GitHub 仓库链接。不要随便填写一个链接,这会导致你的 issue 被直接关闭。 44 | validations: 45 | required: true 46 | 47 | - type: textarea 48 | id: reproduce-steps 49 | attributes: 50 | label: 重现步骤 51 | description: | 52 | 请提供一个最简洁清晰的重现步骤,方便我们快速重现问题。 53 | validations: 54 | required: true 55 | 56 | - type: textarea 57 | id: expected 58 | attributes: 59 | label: 期望的结果是什么? 60 | validations: 61 | required: true 62 | 63 | - type: textarea 64 | id: actually-happening 65 | attributes: 66 | label: 实际的结果是什么? 67 | validations: 68 | required: true 69 | 70 | - type: textarea 71 | id: uni-app 72 | attributes: 73 | label: 环境信息 74 | description: | 75 | 在这里填写你的环境信息 76 | - 发行平台: [如 微信小程序、H5平台、5+ App等] 77 | - 操作系统 [如 iOS 12.1.2、Android 7.0] 78 | - HBuilderX版本 [如使用HBuilderX,则需提供 HBuilderX 版本号] 79 | - uni-app版本 [如使用Vue-cli创建/运行项目,则提供`npm run info`的运行结果] 80 | - 设备信息 [如 iPhone8 Plus] 81 | 82 | 83 | - type: textarea 84 | id: extra 85 | attributes: 86 | label: 其他补充信息 87 | description: | 88 | 根据你的分析,出现这个问题的原因可能在哪里,或者你认为可能产生关联的信息:比如 Vue 版本、vite 版本、Node 版本、采用哪种自动引入方案等,或者进行了哪些配置,使用了哪些插件等信息。 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uni-mini-router 2 | 3 |

4 | 5 | 6 | GitHub Repo stars 7 | 8 | star 9 | 10 | 11 | npm 12 | 13 | 14 | 15 | npm 16 | 17 | 18 | 19 | 20 | 21 | 22 |

23 | 24 |

25 | 🚀 文档网站 (Github)  26 | 🔥 文档网站 (Gitee) 27 |

28 | 29 | --- 30 | 31 | `uni-mini-router`是一个基于`vue3`和`uni-app`框架的轻量级路由库,它提供了类似`Vue Router`的API和功能,旨在帮助开发者使用类似`Vue Router`的方式在uni-app中进行路由跳转、传参、拦截等常用操作。 32 | 33 | `uni-mini-router`支持多种跳转方式,包括普通跳转、重定向、切换TabBar页面等。它也提供了一些高级特性,如路由拦截、编程式导航等。 34 | 35 | 总之,如果你在`uni-app`开发过程中需要使用到路由功能,可以考虑使用`uni-mini-router`来简化你的开发工作。 36 | 37 | ## ✨ 特性 38 | 39 | - 🚀 支持 APP、H5、微信小程序 等平台. 40 | - 💪 支持全局前置导航守卫 beforeEach 和全局后置导航守卫 afterEach. 41 | - 💪 使用 Typescript 构建,提供良好的组件类型系统. 42 | 43 | 44 | ## 链接 45 | 46 | * [意见反馈](https://github.com/Moonofweisheng/uni-mini-router/issues) 47 | * [更新日志](https://moonofweisheng.gitee.io/uni-mini-router/guide/changelog) 48 | * [常见问题](https://moonofweisheng.gitee.io/uni-mini-router/guide/common-problems) 49 | * [Discussions 讨论区](https://github.com/Moonofweisheng/uni-mini-router/discussions) 50 | * [高颜值vue3组件库 Wot Design Uni](https://wot-design-uni.cn/) 51 | * [整合uni-mini-router的起手项目](https://github.com/Moonofweisheng/wot-demo) 52 | 53 | ## 更新日志 54 | 55 | 详细更新日志见 [CHANGELOG](https://github.com/Moonofweisheng/uni-mini-router/blob/master/CHANGELOG.md). 56 | 57 | 58 | ## License 59 | 60 | [MIT](https://github.com/Moonofweisheng/uni-mini-router/blob/master/LICENSE) 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: weisheng 3 | * @Date: 2023-04-23 13:19:59 4 | * @LastEditTime: 2023-04-27 12:45:37 5 | * @LastEditors: weisheng 6 | * @Description:url工具 7 | * @FilePath: \uni-mini-router\src\utils\index.ts 8 | * 记得注释 9 | */ 10 | /** 11 | * 获取url中的参数 12 | * @param path 完整路径 13 | * @returns 14 | */ 15 | export function getUrlParams(path: string) { 16 | const params: Record = {} 17 | const pathArray: string[] = path.split('?') // 路径根据?拆分为2部分 18 | let paramString: string = '' // 参数字符串 19 | let paramArrary: string[] = [] // 参数数组 20 | if (pathArray.length > 1) { 21 | paramString = pathArray[1] 22 | } 23 | paramArrary = paramString.split('&') 24 | for (let index = 0; index < paramArrary.length; index++) { 25 | if (paramArrary[index].split('=').length === 2) { 26 | params[paramArrary[index].split('=')[0]] = paramArrary[index].split('=')[1] 27 | } 28 | } 29 | return params 30 | } 31 | 32 | /** 33 | * 设置参数 34 | * @param path 路径(无参数) 35 | * @param params (参数) 36 | * @returns 37 | */ 38 | export function setUrlParams(path: string, params: Record) { 39 | for (const key in params) { 40 | if (path.indexOf('?') > -1) { 41 | path = path + `&${key}=${params[key]}` 42 | } else { 43 | path = path + `?${key}=${params[key]}` 44 | } 45 | } 46 | return path 47 | } 48 | 49 | /** 50 | * 全量替换url中的字符 51 | * @param str 原始字符串 52 | * @param find 要查找的字符串 53 | * @param replace 要替换的字符串 54 | * @returns 55 | */ 56 | function replaceAll(str: string, find: string, replace: string) { 57 | return str.replace(new RegExp(find, 'g'), replace) 58 | } 59 | 60 | /** 61 | * 去除拼接url产生的多余的/ 62 | * @param url 目标路径 63 | */ 64 | export function beautifyUrl(url: string) { 65 | url = replaceAll(url, '//', '/') // 先替换所有'//'为'/' 66 | url = replaceAll(url, 'https:/', 'https://') // 再将https补全'//' 67 | url = replaceAll(url, 'http:/', 'http://') // 再将http补全'//' 68 | return url 69 | } 70 | /** 71 | * url查询参数序列化 72 | * @param query url查询参数 73 | * @returns 74 | */ 75 | export function queryStringify(query: Record) { 76 | const result: Record = {} 77 | if (query) { 78 | for (const key in query) { 79 | let value: any = query[key] 80 | if (value === undefined) { 81 | value = '' 82 | } 83 | result[key] = value 84 | } 85 | } 86 | return result 87 | } 88 | 89 | /** 90 | * 判断query或params是否为空或者undefined 91 | * @param obj 待判断对象 92 | * @returns 93 | */ 94 | export function isEmptyObject(obj: undefined | null | Record): boolean { 95 | return obj === undefined || obj === null || Object.keys(obj).length === 0 96 | } 97 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uni-mini-router", 3 | "version": "0.1.6", 4 | "description": "", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "scripts": { 8 | "clean:lib": "rimraf lib", 9 | "build:types": "npm run clean:lib && tsc -b ./tsconfig.types.json", 10 | "build": "npm run build:types && rollup -c && node ./typesCopy.js && node ./build/changelog.js", 11 | "dev": "npm run build:types && rollup -c --watch && node ./typesCopy.js", 12 | "lint": "eslint --fix --ext .json,.js,.ts src", 13 | "test": "jest", 14 | "commit": "git-cz", 15 | "release-major": "standard-version --release-as major", 16 | "release-minor": "standard-version --release-as minor", 17 | "release-patch": "standard-version --release-as patch", 18 | "release": "standard-version", 19 | "prerelease": "standard-version --prerelease", 20 | "docs:dev": "vitepress dev docs", 21 | "docs:build": "vitepress build docs", 22 | "docs:serve": "vitepress serve docs" 23 | }, 24 | "config": { 25 | "commitizen": { 26 | "path": "git-cz" 27 | } 28 | }, 29 | "files": [ 30 | "lib" 31 | ], 32 | "lint-staged": { 33 | "*.{js,ts}": "eslint --fix --ext .json,.js,.ts src" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/Moonofweisheng/uni-mini-router.git" 38 | }, 39 | "keywords": [ 40 | "uni-app", 41 | "uni-mini-router", 42 | "router" 43 | ], 44 | "author": "weisheng", 45 | "license": "MIT", 46 | "devDependencies": { 47 | "@babel/core": "^7.21.0", 48 | "@babel/plugin-transform-runtime": "^7.21.0", 49 | "@babel/preset-env": "^7.20.2", 50 | "@babel/preset-typescript": "^7.21.0", 51 | "@commitlint/cli": "^17.4.4", 52 | "@commitlint/config-conventional": "^17.4.4", 53 | "@dcloudio/types": "^3.2.11", 54 | "@rollup/plugin-babel": "^6.0.3", 55 | "@rollup/plugin-commonjs": "^24.0.1", 56 | "@rollup/plugin-json": "^6.0.0", 57 | "@rollup/plugin-node-resolve": "^15.0.1", 58 | "@types/jest": "^29.4.0", 59 | "@types/node": "^18.15.0", 60 | "@typescript-eslint/eslint-plugin": "^5.54.1", 61 | "@typescript-eslint/parser": "^5.54.1", 62 | "commitizen": "^4.3.0", 63 | "cz-conventional-changelog": "^3.3.0", 64 | "element-plus": "^2.4.1", 65 | "eslint": "^8.0.1", 66 | "eslint-config-prettier": "^8.7.0", 67 | "eslint-plugin-import": "^2.25.2", 68 | "eslint-plugin-n": "^15.0.0", 69 | "eslint-plugin-prettier": "^4.2.1", 70 | "eslint-plugin-promise": "^6.0.0", 71 | "git-cz": "^4.9.0", 72 | "husky": "^8.0.3", 73 | "lint-staged": "^13.1.2", 74 | "prettier": "^2.8.4", 75 | "rimraf": "^4.4.0", 76 | "rollup": "2.78.0", 77 | "rollup-plugin-filesize": "9.1.2", 78 | "rollup-plugin-terser": "^7.0.2", 79 | "rollup-plugin-typescript2": "^0.34.1", 80 | "standard-version": "^9.5.0", 81 | "ts-jest": "^29.0.5", 82 | "typescript": "*", 83 | "vitepress": "1.0.0-beta.6", 84 | "vue": "3.2.45" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /docs/guide/installation.md: -------------------------------------------------------------------------------- 1 | # 安装 2 | 本节介绍如何在`uni-app`项目中安装`Uni Mini Router`和生成路由表的插件`uni-read-pages-vite`或`uni-read-pages`。 3 | 4 | ::: tips 5 | 推荐使用[整合uni-mini-router的起手项目](https://github.com/Moonofweisheng/wot-demo),该起手项目已经集成了`uni-mini-router`和`uni-read-pages-vite`,可以直接使用,配置方案也可参考。 6 | ::: 7 | 8 | 9 | ::: code-group 10 | ```bash [npm] 11 | npm i uni-mini-router --save 12 | ``` 13 | 14 | ```bash [yarn] 15 | yarn add uni-mini-router -D 16 | ``` 17 | 18 | ```bash [pnpm] 19 | pnpm add uni-mini-router -D 20 | ``` 21 | ::: 22 | 23 | 24 | 25 | ## 路由表插件安装 26 | 27 | 我们提供了两种方式来生成路由表:[uni-parse-pages](https://www.npmjs.com/package/uni-parse-pages)和[uni-read-pages-vite](https://www.npmjs.com/package/uni-read-pages-vite),这两种方式都可以实现将`pages.json`中的路由信息转化为`uni-mini-router`需要的路由表信息,其中`uni-read-pages-vite`依赖`vite`,在编译时将读取`pages.json`生成的路由表注入全局变量,而`uni-parse-pages`不依赖`vite`,在应用每次热重载时都会从`pages.json`中读取信息生成路由表。 28 | 29 | 由于`uni-app`在编译到小程序端时无法触发`vite`的热更新,所以目前只有使用`uni-parse-pages`生成路由表才可以实现路由信息热更新的功能。 30 | 31 | > 注意!!!`uni-parse-pages`在`uni-mini-router@0.1.0`版本起获得支持,在之前的版本使用会有问题。 32 | 33 | ### 以下两种方式二选一: 34 | 35 | ### 使用uni-parse-pages生成路由表(0.1.0起支持) 36 | 37 | ::: code-group 38 | ```bash [npm] 39 | npm i add uni-parse-pages --save 40 | ``` 41 | 42 | ```bash [yarn] 43 | yarn add add uni-parse-pages -D 44 | ``` 45 | 46 | ```bash [pnpm] 47 | pnpm add add uni-parse-pages -D 48 | ``` 49 | ::: 50 | 51 | 52 | ### 使用uni-read-pages-vite生成路由表 53 | 54 | ::: code-group 55 | ```bash [npm] 56 | npm i add uni-read-pages-vite --save 57 | ``` 58 | 59 | ```bash [yarn] 60 | yarn add add uni-read-pages-vite -D 61 | ``` 62 | 63 | ```bash [pnpm] 64 | pnpm add add uni-read-pages-vite -D 65 | ``` 66 | ::: 67 | 68 | 69 | ## 配置路由表 70 | 71 | :::warning 关于本步骤 72 | 在使用`uni-read-pages-vite`生成路由表时需要进行此项配置,而使用`uni-read-pages`则不需要。 73 | ::: 74 | 75 | 76 | 配置 `vite.config.ts` 通过 `define` 注入全局变量 [查看文档](https://cn.vitejs.dev/config/shared-options.html#define) 77 | 78 | >注意:在 Vite 中使用 `define` 注入的全局变量并不是热更新的,因为这些变量是在构建时被注入到代码中的,而不是在运行时动态生成的。这意味着如果您更新了`page.json`,则需要重新构建应用程序才能使更改生效。 79 | 80 | ### CLI创建的项目配置 81 | ```ts 82 | //vite.config.ts 83 | import { defineConfig } from "vite"; 84 | import uni from "@dcloudio/vite-plugin-uni"; 85 | import TransformPages from 'uni-read-pages-vite' 86 | 87 | export default defineConfig({ 88 | plugins: [uni()], 89 | define: { 90 | ROUTES: new TransformPages().routes, // 注入路由表 91 | } 92 | }); 93 | ``` 94 | 95 | ### HbuilderX创建的项目配置 96 | ```ts 97 | //vite.config.ts 98 | import { defineConfig } from "vite"; 99 | import uni from "@dcloudio/vite-plugin-uni"; 100 | import TransformPages from 'uni-read-pages-vite' 101 | 102 | export default defineConfig({ 103 | plugins: [uni()], 104 | define: { 105 | ROUTES: new TransformPages(__dirname).routes, // 注入路由表 106 | } 107 | }); 108 | ``` 109 | 110 | ### 声明文件`type.d.ts` 111 | `.d.ts`文件的作用是描述`JavaScript`库、模块或其他代码的类型声明和元数据,以便编辑器和开发者能够更好地理解和使用该代码。在编译时,`TypeScript`编译器会使用`.d.ts`文件来验证代码正确性,并帮助开发者在开发过程中提供更好的代码提示和自动补全功能。 112 | 113 | 在项目src目录下(HbuilderX创建的项目可以在根目录下)创建`type.d.ts`文件。 114 | 115 | ```ts 116 | //type.d.ts 117 | declare const ROUTES: [] 118 | ``` 119 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 徐庆凯 3 | * @Date: 2023-03-13 15:48:09 4 | * @LastEditTime: 2023-05-29 14:51:18 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: \uni-mini-router\src\index.ts 8 | * 记得注释 9 | */ 10 | import { routeKey, routerKey } from './symbols' 11 | import { getCurrentPageRoute, navjump, registerEachHooks, rewriteNavMethod, saveCurrRouteByCurrPage } from './router' 12 | import type { AfterEachGuard, BeforeEachGuard, Route, RouteBackLocation, RouteLocationRaw, Router, RouterOptions } from './interfaces' 13 | import { shallowRef, unref } from 'vue' 14 | import { isEmptyObject } from './utils' 15 | /** 16 | * Creates a Router instance that can be used by a Vue app. 17 | * 18 | */ 19 | export function createRouter(options: RouterOptions): Router { 20 | const router: Router = { 21 | routes: options.routes, 22 | guardHooks: { 23 | beforeHooks: null, 24 | afterHooks: null 25 | }, 26 | push(to: RouteLocationRaw) { 27 | return navjump(to, this, 'push') 28 | }, 29 | replace(to: RouteLocationRaw) { 30 | return navjump(to, this, 'replace') 31 | }, 32 | replaceAll(to: RouteLocationRaw) { 33 | return navjump(to, this, 'replaceAll') 34 | }, 35 | pushTab(to: RouteLocationRaw) { 36 | return navjump(to, this, 'pushTab') 37 | }, 38 | back(to?: RouteBackLocation) { 39 | return uni.navigateBack(to) 40 | }, 41 | beforeEach(userGuard: BeforeEachGuard) { 42 | registerEachHooks(router, 'beforeHooks', userGuard) 43 | }, 44 | afterEach(userGuard: AfterEachGuard) { 45 | registerEachHooks(router, 'afterHooks', userGuard) 46 | }, 47 | install: function (app: any): void { 48 | const router = this 49 | app.provide(routerKey, this) 50 | app.provide(routeKey, this.route) 51 | rewriteNavMethod(router) 52 | app.mixin({ 53 | beforeCreate() { 54 | if (this.$mpType === 'page') { 55 | if (router.guardHooks.afterHooks && router.guardHooks.afterHooks[0]) { 56 | const from: Route = router.route.value 57 | const to: Route = getCurrentPageRoute(router) // 当前页面路由信息 58 | router.guardHooks.afterHooks[0].call(null, to, from) 59 | } 60 | } 61 | }, 62 | onLoad(option: Record | undefined) { 63 | if (!isEmptyObject(option) && isEmptyObject(router.route.value.query) && isEmptyObject(router.route.value.params)) { 64 | router.route.value = { ...router.route.value, query: option } 65 | } 66 | }, 67 | onShow() { 68 | if (this.$mpType === 'page') { 69 | saveCurrRouteByCurrPage(router) 70 | } 71 | } 72 | }) 73 | Object.defineProperty(app.config.globalProperties, '$Router', { 74 | get() { 75 | return router 76 | } 77 | }) 78 | Object.defineProperty(app.config.globalProperties, '$Route', { 79 | enumerable: true, 80 | get: () => unref(this.route) 81 | }) 82 | }, 83 | route: shallowRef({ path: '/' }) 84 | } 85 | return router 86 | } 87 | 88 | export * from './core' 89 | export * from './interfaces' 90 | -------------------------------------------------------------------------------- /docs/guide/usage.md: -------------------------------------------------------------------------------- 1 | # 入门 2 | 3 | ## 编程式导航 4 | 5 | >注意:这里`name` 和 `params`搭配使用,而`path` 可以与 `query` 一起使用。 6 | 7 | ### 基础用法 8 | 9 | ```ts 10 | 34 | ``` 35 | 36 | 在user.vue接收传入的对象参数 37 | ```ts 38 | 45 | ``` 46 | ### 传递对象参数 47 | url有长度限制,太长的字符串会传递失败,可改用[窗体通信](https://uniapp.dcloud.net.cn/tutorial/page.html#%E9%A1%B5%E9%9D%A2%E9%80%9A%E8%AE%AF)、[全局变量](https://ask.dcloud.net.cn/article/35021),另外参数中出现空格等特殊字符时需要对参数进行编码,如下为使用encodeURIComponent对参数进行编码的示例。 48 | 49 | ```ts 50 | 69 | ``` 70 | 在user.vue接收传入的对象参数 71 | ```ts 72 | 84 | ``` 85 | 86 | 87 | ## 导航守卫 88 | 89 | `uni-mini-router`支持`全局前置导航守卫 beforeEach`和`全局后置导航守卫 afterEach`,主要用来通过跳转或取消的方式守卫导航。 90 | 91 | #### 全局前置守卫 beforeEach 92 | 你可以使用 `router.beforeEach` 注册一个全局前置守卫: 93 | 94 | ```ts 95 | const router = createRouter({ ... }) 96 | 97 | router.beforeEach((to, from, next) => { 98 | // next入参 false 以取消导航 99 | next(false) 100 | }) 101 | ``` 102 | ##### `beforeEach`守卫方法接收三个参数: 103 | - `to`: 即将要进入的目标 104 | - `from`: 当前导航正要离开的路由 105 | - `next`: 用于reslove `beforeEach`钩子,需要确保 `next` 在导航守卫中都被严格调用一次- 106 | - `next()`: 执行默认路由跳转逻辑 107 | - `next(false)`: 终止跳转逻辑 108 | - `next({ path: '/' })`: 跳转到不同的页面 109 | - `next({ path: '/', navType: 'replaceAll' })`: 改变当前跳转类型并跳转到不同的页面,可以通过`navType`指定新的跳转类型。(实例为中断当前导航,改用`replaceAll`方法跳转到新的页面) 110 | 111 | ### 全局后置钩子 afterEach 112 | 你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身 113 | 114 | ```ts 115 | const router = createRouter({ ... }) 116 | 117 | router.afterEach((to, from) => { 118 | console.log(to) 119 | console.log(from) 120 | }) 121 | ``` 122 | 它对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。 123 | 124 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles/custom.css: -------------------------------------------------------------------------------- 1 | ul { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | ul { 7 | list-style: none; 8 | } 9 | 10 | a { 11 | text-decoration: none; 12 | } 13 | 14 | a, 15 | a:active { 16 | color: #34495e; 17 | } 18 | 19 | 20 | .style-block { 21 | display: inline-block; 22 | width: 180px; 23 | padding: 15px; 24 | margin-right: 20px; 25 | margin-bottom: 20px; 26 | border-radius: 4px; 27 | color: #fff; 28 | } 29 | 30 | .style-block p { 31 | margin: 0; 32 | color: #fff; 33 | } 34 | 35 | .a-dot, 36 | .b-dot { 37 | position: absolute; 38 | border-radius: 50%; 39 | width: 12px; 40 | height: 12px; 41 | background: #668df8; 42 | z-index: 10; 43 | border: 2px solid #fff; 44 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .09); 45 | } 46 | 47 | .a-dot { 48 | left: -6px; 49 | top: -6px; 50 | } 51 | 52 | .a-dot:before { 53 | content: "A"; 54 | display: inline-block; 55 | color: rgba(0, 0, 0, .85); 56 | font-size: 17px; 57 | -webkit-transform: translate(14px, -22px); 58 | transform: translate(14px, -22px); 59 | } 60 | 61 | .b-dot { 62 | right: -6px; 63 | bottom: -6px; 64 | } 65 | 66 | .b-dot:before { 67 | content: "B"; 68 | display: inline-block; 69 | color: rgba(0, 0, 0, .85); 70 | font-size: 17px; 71 | -webkit-transform: translate(14px, -22px); 72 | transform: translate(14px, -22px); 73 | } 74 | 75 | .liner-color { 76 | width: 160px; 77 | height: 160px; 78 | position: relative; 79 | } 80 | 81 | .liner-color:after { 82 | position: absolute; 83 | content: ""; 84 | width: 2px; 85 | height: 250px; 86 | right: 79px; 87 | top: 50%; 88 | background-color: #fff; 89 | -webkit-transform: translateY(-50%) rotate(-45deg); 90 | transform: translateY(-50%) rotate(-45deg); 91 | } 92 | 93 | .color-wrapper { 94 | position: relative; 95 | display: flex; 96 | align-items: center; 97 | } 98 | 99 | .color-block { 100 | width: 65px; 101 | vertical-align: middle; 102 | display: inline-block; 103 | text-align: center; 104 | height: 20px; 105 | color: #fff; 106 | font-size: 14px; 107 | margin-left: 5px; 108 | } 109 | 110 | .liner-color1:after { 111 | -webkit-transform: translateY(-50%) rotate(45deg); 112 | transform: translateY(-50%) rotate(45deg); 113 | } 114 | 115 | .liner-color1 .a-dot { 116 | right: -6px; 117 | top: -6px; 118 | left: inherit; 119 | } 120 | 121 | .liner-color1 .b-dot { 122 | left: -6px; 123 | bottom: -6px; 124 | } 125 | 126 | .liner-color1 .b-dot:before { 127 | -webkit-transform: translate(25px, -15px); 128 | transform: translate(25px, -15px); 129 | } 130 | 131 | .demo-right { 132 | position: absolute; 133 | left: 250px; 134 | } 135 | 136 | .color-group { 137 | display: flex; 138 | flex-wrap: wrap; 139 | padding-left: 0 !important; 140 | box-sizing: border-box; 141 | } 142 | 143 | .color-group.dark { 144 | background: #262626; 145 | border: 3px solid #262626; 146 | border-radius: 4px; 147 | } 148 | 149 | .color-group li { 150 | width: 120px; 151 | height: 120px; 152 | list-style: none; 153 | display: inline-block; 154 | padding: 8px 0 0 8px; 155 | } 156 | .color-group-line{ 157 | margin-top:0 !important; 158 | margin-bottom: 8px; 159 | } 160 | 161 | .color-group li div { 162 | font-weight: 500; 163 | } -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/frame.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 36 | 129 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles/vars.css: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Colors 4 | * -------------------------------------------------------------------------- */ 5 | 6 | :root { 7 | --vp-c-brand: #4d80f0; 8 | /* 20 */ 9 | --vp-c-brand-light: #7199f3; 10 | /* 30 */ 11 | --vp-c-brand-lighter: #7199f3; 12 | /* 35 */ 13 | --vp-c-brand-lightest: #8bacf5; 14 | /* 10 */ 15 | --vp-c-brand-dark: #4573d8; 16 | /* 20 */ 17 | --vp-c-brand-darker: #3e66c0; 18 | --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); 19 | } 20 | 21 | /** 22 | * Component: Button 23 | * -------------------------------------------------------------------------- */ 24 | 25 | :root { 26 | --vp-button-brand-border: var(--vp-c-brand-light); 27 | --vp-button-brand-text: var(--vp-c-white); 28 | --vp-button-brand-bg: var(--vp-c-brand); 29 | --vp-button-brand-hover-border: var(--vp-c-brand-light); 30 | --vp-button-brand-hover-text: var(--vp-c-white); 31 | --vp-button-brand-hover-bg: var(--vp-c-brand-light); 32 | --vp-button-brand-active-border: var(--vp-c-brand-light); 33 | --vp-button-brand-active-text: var(--vp-c-white); 34 | --vp-button-brand-active-bg: var(--vp-button-brand-bg); 35 | } 36 | 37 | /** 38 | * Component: Home 39 | * -------------------------------------------------------------------------- */ 40 | 41 | :root { 42 | --vp-home-hero-name-color: transparent; 43 | --vp-home-hero-name-background: -webkit-linear-gradient( 44 | 120deg, 45 | #4d80f0 30%, 46 | #bd34fe 47 | ); 48 | 49 | --vp-home-hero-image-background-image: linear-gradient( 50 | -45deg, 51 | #bd34fe 50%, 52 | #4d80f0 50% 53 | ); 54 | --vp-home-hero-image-filter: blur(40px); 55 | } 56 | 57 | @media (min-width: 640px) { 58 | :root { 59 | --vp-home-hero-image-filter: blur(56px); 60 | } 61 | } 62 | 63 | @media (min-width: 960px) { 64 | :root { 65 | --vp-home-hero-image-filter: blur(72px); 66 | } 67 | } 68 | 69 | /** 70 | * Component: Custom Block 71 | * -------------------------------------------------------------------------- */ 72 | 73 | :root { 74 | --vp-custom-block-tip-border: var(--vp-c-brand); 75 | --vp-custom-block-tip-text: var(--vp-c-brand-darker); 76 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 77 | } 78 | 79 | .dark { 80 | --vp-custom-block-tip-border: var(--vp-c-brand); 81 | --vp-custom-block-tip-text: var(--vp-c-brand-lightest); 82 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 83 | } 84 | 85 | /** 86 | * Component: Algolia 87 | * -------------------------------------------------------------------------- */ 88 | 89 | .DocSearch { 90 | --docsearch-primary-color: var(--vp-c-brand) !important; 91 | } 92 | 93 | /** 94 | * VitePress: Custom fix 95 | * -------------------------------------------------------------------------- */ 96 | 97 | /* 98 | Use lighter colors for links in dark mode for a11y. 99 | Also specify some classes twice to have higher specificity 100 | over scoped class data attribute. 101 | */ 102 | .dark .vp-doc a, 103 | .dark .vp-doc a > code, 104 | .dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, 105 | .dark .VPNavBarMenuLink.VPNavBarMenuLink.active, 106 | .dark .link.link:hover, 107 | .dark .link.link.active, 108 | .dark .edit-link-button.edit-link-button, 109 | .dark .pager-link .title { 110 | color: var(--vp-c-brand-lighter); 111 | } 112 | 113 | .dark .vp-doc a:hover, 114 | .dark .vp-doc a > code:hover { 115 | color: var(--vp-c-brand-lightest); 116 | opacity: 1; 117 | } 118 | 119 | /* Transition by color instead of opacity */ 120 | .dark .vp-doc .custom-block a { 121 | transition: color 0.25s; 122 | } 123 | 124 | .vp-sponsor.aside .vp-sponsor-grid.mini .vp-sponsor-grid-image { 125 | max-width: 124px; 126 | } 127 | 128 | 129 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release Tag 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' # 推送标签,比如 v1.0, v20.15.10 7 | 8 | jobs: 9 | build: 10 | name: 创建发布 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: 检出代码 15 | uses: actions/checkout@v2 16 | 17 | - name: 获取当前和上一个标签 18 | id: get_tags 19 | run: | 20 | git fetch --prune --unshallow 21 | tags=($(git tag -l --sort=-version:refname)) 22 | current_tag=${tags[0]} 23 | previous_tag=${tags[1]} 24 | echo "::set-output name=current_tag::$current_tag" 25 | echo "::set-output name=previous_tag::$previous_tag" 26 | 27 | - name: 提取并分类提交消息 28 | id: extract_commit_messages 29 | run: | 30 | set -e 31 | current_tag="${{ steps.get_tags.outputs.current_tag }}" 32 | previous_tag="${{ steps.get_tags.outputs.previous_tag }}" 33 | commit_messages=$(git log --pretty=format:"%s %h" "$previous_tag".."$current_tag" | grep -E 'feat|fix|docs|perf') 34 | feat_messages=$(echo "$commit_messages" | grep 'feat' || true) 35 | fix_messages=$(echo "$commit_messages" | grep 'fix' || true) 36 | docs_messages=$(echo "$commit_messages" | grep 'docs' || true) 37 | perf_messages=$(echo "$commit_messages" | grep 'perf' || true) 38 | echo "::set-output name=feat_messages::${feat_messages[@]}" 39 | echo "::set-output name=fix_messages::${fix_messages[@]}" 40 | echo "::set-output name=docs_messages::${docs_messages[@]}" 41 | echo "::set-output name=perf_messages::${perf_messages[@]}" 42 | 43 | - name: 获取当前分支名 44 | id: get_branch_name 45 | run: | 46 | branch_name=$(git rev-parse --abbrev-ref HEAD) 47 | echo "::set-output name=branch_name::$branch_name" 48 | 49 | - name: 发布说明 50 | id: generate_release_notes 51 | run: | 52 | # 提取提交消息分类 53 | feat_messages=("${{ steps.extract_commit_messages.outputs.feat_messages }}") 54 | fix_messages=("${{ steps.extract_commit_messages.outputs.fix_messages }}") 55 | docs_messages=("${{ steps.extract_commit_messages.outputs.docs_messages }}") 56 | perf_messages=("${{ steps.extract_commit_messages.outputs.perf_messages }}") 57 | 58 | # 生成发布说明的Markdown字符串 59 | release_notes="> 请查看 [更新日志](./CHANGELOG.md) 获取所有变更详情。 \n## 更新内容: \n" 60 | 61 | if [[ -n "$feat_messages" ]]; then 62 | release_notes="$release_notes\n### ✨ Features | 新功能: \n" 63 | for message in "${feat_messages[@]}"; do 64 | release_notes="$release_notes\n- $message" 65 | done 66 | fi 67 | 68 | if [[ -n "$fix_messages" ]]; then 69 | release_notes="$release_notes\n### 🐛 Bug Fixes | Bug 修复: \n" 70 | for message in "${fix_messages[@]}"; do 71 | release_notes="$release_notes\n- $message" 72 | done 73 | fi 74 | 75 | if [[ -n "$docs_messages" ]]; then 76 | release_notes="$release_notes\n### ✏️ Documentation | 文档: \n" 77 | for message in "${docs_messages[@]}"; do 78 | release_notes="$release_notes\n- $message" 79 | done 80 | fi 81 | 82 | if [[ -n "$perf_messages" ]]; then 83 | release_notes="$release_notes\n### ⚡ Performance Improvements | 性能优化: \n" 84 | for message in "${perf_messages[@]}"; do 85 | release_notes="$release_notes\n- $message" 86 | done 87 | fi 88 | echo "::set-output name=release_notes::$release_notes" 89 | 90 | 91 | - name: 写入生成的发布说明到 changelog.md 92 | run: | 93 | echo -e "${{ steps.generate_release_notes.outputs.release_notes }}" > changelog.md 94 | cat changelog.md 95 | 96 | - name: 创建标签的发布 97 | id: release_tag 98 | uses: ncipollo/release-action@v1 99 | with: 100 | generateReleaseNotes: "false" # 禁用自动生成发布说明 101 | bodyfile: changelog.md 102 | -------------------------------------------------------------------------------- /src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 徐庆凯 3 | * @Date: 2023-03-13 15:48:09 4 | * @LastEditTime: 2023-07-06 16:07:30 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: \uni-mini-router\src\interfaces\index.ts 8 | * 记得注释 9 | */ 10 | /* eslint-disable @typescript-eslint/ban-types */ 11 | 12 | import { Ref } from 'vue' 13 | 14 | /** 15 | * Router instance. 16 | */ 17 | export interface Router { 18 | route: Ref // 当前路由信息 19 | routes: any // 路由表 20 | readonly guardHooks: GuardHooksConfig // 守卫钩子 21 | back(to?: RouteBackLocation): void 22 | push(to: RouteLocationRaw): void 23 | replace(to: RouteLocationRaw): void 24 | replaceAll(to: RouteLocationRaw): void 25 | pushTab(to: RouteLocationRaw): void 26 | beforeEach(userGuard: BeforeEachGuard): void // 全局前置路由守卫 27 | afterEach(userGuard: AfterEachGuard): void // 全局后置路由守卫 28 | install(App: any): void 29 | } 30 | 31 | export type BeforeEachGuard = (to: Route, from: Route, next: (rule?: NextRouteLocationRaw | boolean) => void) => void | Promise // 全局前置守卫函数 32 | export type AfterEachGuard = (to: Route, from: Route) => void // 全局后置守卫函数 33 | 34 | export interface GuardHooksConfig { 35 | beforeHooks: BeforeEachGuard[] // 前置钩子 36 | afterHooks: AfterEachGuard[] // 后置钩子 37 | } 38 | 39 | export interface RouteLocationBase { 40 | animationType?: StartAnimationType | EndAnimationType // 动画类型 41 | animationDuration?: number // 动画时间 42 | } 43 | 44 | export type StartAnimationType = 45 | | 'slide-in-right' 46 | | 'slide-in-left' 47 | | 'slide-in-top' 48 | | 'slide-in-bottom' 49 | | 'pop-in' 50 | | 'fade-in' 51 | | 'zoom-out' 52 | | 'zoom-fade-out' 53 | | 'none' 54 | export type EndAnimationType = 55 | | 'slide-out-right' 56 | | 'slide-out-left' 57 | | 'slide-out-top' 58 | | 'slide-out-bottom' 59 | | 'pop-out' 60 | | 'fade-out' 61 | | 'zoom-in' 62 | | 'zoom-fade-in' 63 | | 'none' 64 | 65 | // name与params组合 66 | export interface RouteNameLocation extends RouteLocationBase { 67 | name: string // 路由名称 68 | params?: Record // 参数 69 | } 70 | 71 | // path与query组合 72 | export interface RoutePathLocation extends RouteLocationBase { 73 | path: string // 路由路径 74 | query?: Record // 参数 75 | } 76 | 77 | // back方法参数 78 | export interface RouteBackLocation extends RouteLocationBase { 79 | animationType: EndAnimationType 80 | delta?: number // 返回的页面数,如果 delta 大于现有页面数,则返回到首页。 81 | } 82 | 83 | export type RouteUrlLocation = string 84 | export type RouteLocationRaw = RouteUrlLocation | RouteNameLocation | RoutePathLocation // 路由位置 85 | 86 | // 创建路由实例的选项 87 | export interface RouterOptions { 88 | routes: any 89 | } 90 | 91 | // 路由信息 92 | export interface Route { 93 | fullPath?: string 94 | aliasPath?: string 95 | name?: string 96 | path?: string 97 | query?: Record 98 | params?: Record 99 | } 100 | // 导航类型 101 | export type NAVTYPE = 'push' | 'replace' | 'replaceAll' | 'pushTab' | 'back' 102 | export type NavMethodType = 'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab' | 'navigateBack' 103 | 104 | // 导航类型枚举 105 | export enum NavTypeEnum { 106 | push = 'navigateTo', 107 | replace = 'redirectTo', 108 | replaceAll = 'reLaunch', 109 | pushTab = 'switchTab', 110 | back = 'navigateBack' 111 | } 112 | 113 | // 导航类型枚举反向映射 114 | // export enum NavTypeReverseEnum { 115 | // navigateTo = 'push', 116 | // redirectTo = 'replace', 117 | // reLaunch = 'replaceAll', 118 | // switchTab = 'pushTab', 119 | // navigateBack = 'back' 120 | // } 121 | export type HookType = 'beforeHooks' | 'afterHooks' 122 | export const NavMethod: NavMethodType[] = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab', 'navigateBack'] 123 | 124 | // next方法 125 | // name与params组合 126 | export interface NextRouteNameLocation extends RouteNameLocation { 127 | navType?: NAVTYPE // 导航类型 128 | } 129 | 130 | // path与query组合 131 | export interface NextRoutePathLocation extends RoutePathLocation { 132 | navType?: NAVTYPE // 导航类型 133 | } 134 | 135 | // back方法参数 136 | export interface NextRouteBackLocation extends RouteBackLocation { 137 | navType?: NAVTYPE // 导航类型 138 | } 139 | 140 | // Next方法入参 141 | export type NextRouteLocationRaw = RouteUrlLocation | NextRouteNameLocation | NextRoutePathLocation | NextRouteBackLocation 142 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /* 3 | * @Author: 徐庆凯 4 | * @Date: 2022-11-18 14:56:37 5 | * @LastEditTime: 2023-04-27 15:23:38 6 | * @LastEditors: weisheng 7 | * @Description: 8 | * @FilePath: \uni-mini-router\rollup.config.js 9 | * 记得注释 10 | */ 11 | import path from 'path' 12 | import resolve from '@rollup/plugin-node-resolve' 13 | import commonjs from '@rollup/plugin-commonjs' 14 | import rollupTypescript from 'rollup-plugin-typescript2' 15 | import babel from '@rollup/plugin-babel' 16 | import json from '@rollup/plugin-json' 17 | import fs from 'fs' 18 | import filesize from 'rollup-plugin-filesize' // 打包后在控制台显示文件大小。 19 | 20 | import { 21 | DEFAULT_EXTENSIONS 22 | } from '@babel/core' 23 | import { 24 | terser 25 | } from 'rollup-plugin-terser' 26 | import pkg from './package.json' 27 | 28 | const now = new Date() 29 | 30 | const banner = `/*! 31 | * ${pkg.name} v${pkg.version} 32 | * ${now.getFullYear()}/${now.getMonth()+1}/${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} weisheng 33 | */` 34 | const componentRoot = path.join(__dirname, './src') 35 | const componentNames = fs 36 | // 获取所有文件夹及文件 37 | .readdirSync(`${componentRoot}`, { 38 | withFileTypes: true 39 | }) 40 | // 筛选出所有文件夹 41 | .filter((p) => { 42 | return p.isDirectory() && fs.existsSync(`${componentRoot}/${p.name}/index.ts`) 43 | }) 44 | // 数据预处理 45 | .map((p) => { 46 | return { 47 | path: `${p.name}/index`, 48 | name: p.name 49 | } 50 | }) 51 | // 当前运行环境,可通过 cross-env 命令行设置 52 | // const env = process.env.NODE_ENV 53 | // umd/iife 模式的编译结果文件输出的全局变量名称 54 | let output = [ 55 | // es module 56 | { 57 | // package.json 配置的 module 属性 58 | file: pkg.main, 59 | format: 'es', 60 | banner 61 | }, 62 | ] 63 | 64 | function createConfigs() { 65 | let configs = output.map((o) => { 66 | const config = { 67 | // 入口文件,src/index.ts 68 | input: path.resolve(__dirname, 'src/index.ts'), 69 | // 输出文件 70 | output: o, 71 | external: o.format === 'es' ? ['vue', 'qs'] : [], 72 | plugins: [ 73 | // 解析第三方依赖 74 | resolve({ 75 | jsnext: true, 76 | preferBuiltins: true, 77 | browser: true 78 | }), 79 | // 识别 commonjs 模式第三方依赖 80 | commonjs(), 81 | // rollup 编译 typescript 82 | rollupTypescript(), 83 | // babel 配置 84 | babel({ 85 | // 编译库使用 runtime 86 | babelHelpers: 'runtime', 87 | // 只转换源代码,不转换外部依赖 88 | exclude: 'node_modules/**', 89 | // babel 默认不支持 ts 需要手动添加 90 | extensions: [...DEFAULT_EXTENSIONS, '.ts'] 91 | }), 92 | // 解析json 93 | json(), 94 | filesize(), 95 | terser({ 96 | compress: { 97 | pure_getters: true, 98 | unsafe: true, 99 | unsafe_comps: true, 100 | warnings: false 101 | } 102 | }) 103 | ] 104 | } 105 | return config 106 | }) 107 | 108 | let config = { 109 | input: componentNames.reduce((result, p) => { 110 | let key = p.path 111 | result[key] = `${componentRoot}/${p.path.replace(/\/index/g, '')}` 112 | return result 113 | }, {}), 114 | output: { 115 | dir: 'lib', 116 | chunkFileNames: 'esm.js', 117 | format: 'es', 118 | banner: banner 119 | }, 120 | treeshake: true, 121 | external: ['vue', 'qs'], 122 | plugins: [ 123 | // 解析第三方依赖 124 | resolve({ 125 | jsnext: true, 126 | preferBuiltins: true, 127 | browser: true, 128 | extensions: [...DEFAULT_EXTENSIONS, '.ts', '.tsx'] 129 | }), 130 | // 识别 commonjs 模式第三方依赖 131 | commonjs(), 132 | // rollup 编译 typescript 133 | rollupTypescript(), 134 | // babel 配置 135 | babel({ 136 | // 编译库使用 runtime 137 | babelHelpers: 'runtime', 138 | // 只转换源代码,不转换外部依赖 139 | exclude: 'node_modules/**', 140 | // babel 默认不支持 ts 需要手动添加 141 | extensions: [...DEFAULT_EXTENSIONS, '.ts', '.tsx'] 142 | }), 143 | // 解析json 144 | json(), 145 | filesize(), 146 | terser({ 147 | compress: { 148 | pure_getters: true, 149 | unsafe: true, 150 | unsafe_comps: true, 151 | warnings: false 152 | } 153 | }) 154 | ] 155 | } 156 | return [...configs, config] 157 | } 158 | export default createConfigs() -------------------------------------------------------------------------------- /docs/guide/quick-use.md: -------------------------------------------------------------------------------- 1 | # 快速上手 2 | 本节介绍如何在`uni-app`项目中配置并使用 `Uni Mini Router`。 3 | 4 | 5 | ## 配置路由 6 | 项目src目录下(HbuilderX创建的项目可以在根目录下)创建router文件夹,并在该文件夹创建`index.ts`,可以根据生成路由表方式的不同,我们这里也提供了两种配置router的方式,也是二选一 7 | 8 | 9 | ### 方式1:uni-parse-pages 10 | ```ts 11 | import { createRouter } from 'uni-mini-router' 12 | // 导入pages.json 13 | import pagesJson from '../pages.json' 14 | // 引入uni-parse-pages 15 | import pagesJsonToRoutes from 'uni-parse-pages' 16 | // 生成路由表 17 | const routes = pagesJsonToRoutes(pagesJson) 18 | const router = createRouter({ 19 | routes: [...routes] // 路由表信息 20 | }) 21 | export default router 22 | ``` 23 | 24 | ### 方式2:uni-read-pages-vite 25 | 26 | ```ts 27 | import { createRouter } from 'uni-mini-router' 28 | const router = createRouter({ 29 | routes: [...ROUTES] // 路由表信息 30 | }) 31 | export default router 32 | ``` 33 | 34 | ## 配置main.ts 35 | 36 | ```ts 37 | import { createSSRApp } from 'vue' 38 | import App from './App.vue' 39 | import router from './router' 40 | export function createApp() { 41 | const app = createSSRApp(App) 42 | app.use(router) 43 | return { 44 | app 45 | } 46 | } 47 | ``` 48 | 49 | ## 配置pages.json 50 | 在pages.json中为页面路由指定`name`字段后,即可以使用`name`跳转 51 | >注意:此处定义的`name`字段必须全局唯一。 52 | ```json 53 | // pages.json 54 | { 55 | "pages": [{ 56 | "path": "pages/home/Home", 57 | "name": "home", // 路由 name 用于命名路由的跳转 58 | "style": { 59 | "mp-alipay": { 60 | "allowsBounceVertical": "NO" 61 | }, 62 | "navigationBarTitleText": "首页" 63 | } 64 | }, 65 | { 66 | "path": "pages/login/Login", 67 | "name": "login", 68 | "style": { 69 | "mp-alipay": { 70 | "allowsBounceVertical": "NO" 71 | }, 72 | "navigationBarTitleText": "" 73 | } 74 | }, 75 | { 76 | "path": "pages/mine/Mine", 77 | "name": "mine", 78 | "style": { 79 | "navigationBarTitleText": "", 80 | "navigationBarBackgroundColor": "#E7F0FF" 81 | } 82 | } 83 | ], 84 | "tabBar": { 85 | "color": "#bfbfbf", 86 | "selectedColor": "#0165FF", 87 | "backgroundColor": "#ffffff", 88 | "list": [{ 89 | "pagePath": "pages/home/Home", 90 | "iconPath": "static/icon_home.png", 91 | "selectedIconPath": "static/icon_home_selected.png", 92 | "text": "首页" 93 | }, 94 | { 95 | "pagePath": "pages/mine/Mine", 96 | "iconPath": "static/icon_mine.png", 97 | "selectedIconPath": "static/icon_mine_selected.png", 98 | "text": "我的" 99 | } 100 | ] 101 | }, 102 | "globalStyle": { 103 | "navigationBarTextStyle": "black", 104 | "navigationBarBackgroundColor": "#FFF", 105 | "backgroundColor": "#F8F8F8" 106 | } 107 | } 108 | ``` 109 | ## 配置自动按需导入(可选) 110 | [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import):是一个为 `Vite`、`Webpack`、`Rollup` 和 `esbuild` 按需自动导入 API,支持 `TypeScript`的插件,我们基于此插件实现自动按需导入。 111 | 112 | 不使用按需导入,则需要手动`import` 113 | ```ts 114 | import { useRouter } from 'uni-mini-router' 115 | const router = useRouter() 116 | router.push('/') 117 | ``` 118 | 119 | 使用按需导入后 120 | ```ts 121 | const router = useRouter() 122 | router.push('/') 123 | ``` 124 | 125 | ### 安装`unplugin-auto-import` 126 | ```sh 127 | yarn add uni-mini-router -D 128 | ``` 129 | 130 | ### 配置`unplugin-auto-import` 131 | 详细配置方案见[unplugin-auto-import](https://github.com/antfu/unplugin-auto-import),这里给出支持`uni-mini-router`的简易配置 132 | ```ts 133 | //vite.config.ts 134 | import { defineConfig } from 'vite' 135 | import TransformPages from 'uni-read-pages-vite' 136 | import uni from '@dcloudio/vite-plugin-uni' 137 | import AutoImport from 'unplugin-auto-import/vite' 138 | export default defineConfig({ 139 | base: './', 140 | plugins: [ 141 | uni(), 142 | AutoImport({ 143 | imports: [ 144 | 'vue', 145 | 'uni-app', 146 | 'pinia', 147 | { 148 | from: 'uni-mini-router', 149 | imports: ['createRouter', 'useRouter', 'useRoute'] 150 | } 151 | ], 152 | dts: 'src/auto-imports.d.ts', // 这里src目录必须是已存在的,如果是HbuilderX创建的项目是没有src目录的,可以配置为 dts: 'auto-imports.d.ts' 153 | eslintrc: { 154 | enabled: true, 155 | globalsPropValue: true 156 | } 157 | }) 158 | ], 159 | define: { 160 | ROUTES: new TransformPages().routes 161 | } 162 | }) 163 | ``` 164 | #### 总结 165 | `unplugin-auto-import` 可以帮助我们实现按需自动导入第三方库的API,提升开发效率,但是它也同样存在一些缺点,例如: 166 | - 可能会影响代码可读性:自动导入模块可能会导致代码可读性降低,因为开发者可能不知道哪些模块被自动导入了。 167 | 168 | - 可能会导致性能问题:自动导入模块可能会导致性能问题,因为它需要扫描整个代码库来查找缺失的模块。 169 | 170 | 所以在提升开发效率的同时也要兼顾可读性和性能问题,尽量将一些被广泛认知和使用、不用关注实现、不变的内容作为自动按需引入的对象,而项目内的代码如果自动按需引入是否会增加开发人员的心智负担,则需要我们做出相应的权衡。 171 | -------------------------------------------------------------------------------- /docs/.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: weisheng 3 | * @Date: 2023-07-27 10:26:09 4 | * @LastEditTime: 2025-02-26 23:33:48 5 | * @LastEditors: weisheng 6 | * @Description: 7 | * @FilePath: /uni-mini-router/docs/.vitepress/config.ts 8 | * 记得注释 9 | */ 10 | import { defineConfig } from 'vitepress'; 11 | 12 | export default defineConfig({ 13 | base: process.env.BASE_URL || "/uni-mini-router/", 14 | title: `Uni Mini Router`, 15 | description: '一个基于vue3和Typescript的轻量级uni-app路由库', 16 | head: [ 17 | ['link', { rel: 'icon', href: `${process.env.BASE_URL || "/uni-mini-router/"}favicon.ico` }], 18 | ['script', {}, ` 19 | var _hmt = _hmt || []; 20 | (function() { 21 | var hm = document.createElement("script"); 22 | hm.src = "https://hm.baidu.com/hm.js?43e96134ee5fd0ab364786f7a00a1048"; 23 | var s = document.getElementsByTagName("script")[0]; 24 | s.parentNode.insertBefore(hm, s); 25 | })(); 26 | `] 27 | ], 28 | themeConfig: { 29 | logo: '/logo.png', 30 | lastUpdated: { 31 | text: '最后更新' 32 | }, 33 | editLink: { 34 | pattern: 'https://github.com/Moonofweisheng/uni-mini-router/edit/master/docs/:path', 35 | text: '为此页提供修改建议', 36 | }, 37 | socialLinks: [ 38 | { icon: 'github', link: 'https://github.com/Moonofweisheng/uni-mini-router' }, 39 | { icon: { svg: '' }, link: "https://gitee.com/fant-mini/uni-mini-router", ariaLabel: 'Gitee' }, 40 | { icon: { svg: '' }, link: "https://qm.qq.com/cgi-bin/qm/qr?k=O1Z3pal6StL39qHtABqR54Tb56igr90O&jump_from=webapi&authKey=MtVWfi/EQbT03wW7tKXv4bmyKYHBHtzI8VewlzSsOdxFjN0wbgNy17np9Z9yC4Z8", ariaLabel: 'QQ' } 41 | ], 42 | search: { 43 | provider: 'algolia', 44 | options: { 45 | appId: 'OOURGSMU49', 46 | apiKey: 'ab86779c0c2d0fc6e2ba6064d6eac1f5', 47 | indexName: 'uni-mini-router', 48 | }, 49 | }, 50 | 51 | footer: { 52 | message: `Released under the MIT License.`, 53 | copyright: 'Copyright © 2023-present weisheng', 54 | }, 55 | nav: [ 56 | { text: '指南', link: '/guide/installation',activeMatch: '/guide/'}, 57 | { text: '捐赠作者', link: '/reward/reward', activeMatch: '/reward/' }, 58 | { 59 | text: 'Wot Design Uni', 60 | link: 'https://wot-design-uni.netlify.app/' 61 | }, 62 | ], 63 | sidebar: { 64 | '/guide/': [ 65 | { 66 | text: '介绍', 67 | link: '/guide/introduction', 68 | }, 69 | { 70 | text: '安装', 71 | link: '/guide/installation', 72 | }, 73 | { 74 | text: '配置', 75 | link: '/guide/quick-use', 76 | }, 77 | { 78 | text: '入门', 79 | link: '/guide/usage', 80 | }, 81 | { 82 | text: 'API文档', 83 | link: '/guide/api', 84 | }, 85 | { 86 | text: '更新日志', 87 | link: '/guide/changelog', 88 | }, 89 | { 90 | text: '常见问题', 91 | link: '/guide/common-problems', 92 | } 93 | ], 94 | '/reward/': [ 95 | { 96 | text: '捐赠作者', 97 | link: '/reward/reward', 98 | }, 99 | ] 100 | } 101 | 102 | }, 103 | 104 | }) -------------------------------------------------------------------------------- /docs/guide/changelog.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | 3 | 4 | ### [0.1.4](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.3...v0.1.4) (2023-08-09) 5 | 6 | 7 | ### ✏️ Documentation | 文档 8 | 9 | * ✏️ 增加联系方式 ([271c3db](https://gitee.com/fant-mini/uni-mini-router/commit/271c3db37fe4c95444d1f3676f8ea7b8948b50d0)) 10 | 11 | 12 | ### 🐛 Bug Fixes | Bug 修复 13 | 14 | * 🐛 修复前置导航守卫H5端打包后不执行的问题 ([13a1c11](https://gitee.com/fant-mini/uni-mini-router/commit/13a1c1180c9d4f53486fe275dd01071a1fa3240b)) 15 | 16 | ### [0.1.3](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.2...v0.1.3) (2023-07-07) 17 | 18 | 19 | ### 🐛 Bug Fixes | Bug 修复 20 | 21 | * 🐛 修复前置导航守卫非async时失效的问题 ([024ea1e](https://gitee.com/fant-mini/uni-mini-router/commit/024ea1e00b2257a5a6cd1d0ac20b22aa9b2095bf)) 22 | 23 | ### [0.1.2](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.1...v0.1.2) (2023-07-06) 24 | 25 | 26 | ### 🐛 Bug Fixes | Bug 修复 27 | 28 | * 🐛 修复在前置导航守卫中使用async/await导致无法跳转的问题 ([f385b9e](https://gitee.com/fant-mini/uni-mini-router/commit/f385b9e5558a7174de05174031666574870282d4)) 29 | 30 | ### [0.1.1](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.0...v0.1.1) (2023-05-31) 31 | 32 | 33 | ### 🐛 Bug Fixes | Bug 修复 34 | 35 | * 🐛 修复当前路由信息修改后会影响路由表信息的问题 ([c8f076e](https://gitee.com/fant-mini/uni-mini-router/commit/c8f076e0cd41f26788d2f8f76fda18eed8fd759c)) 36 | 37 | ## [0.1.0](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.12...v0.1.0) (2023-05-31) 38 | 39 | 40 | ### ✨ Features | 新功能 41 | 42 | * ✨ 优化 useRoute 的取值逻辑,新增在onShow周期更新route的逻辑 ([3b6bb8e](https://gitee.com/fant-mini/uni-mini-router/commit/3b6bb8e776a35872f0261c78482f9bf2e00e4f87)) 43 | 44 | 45 | ### ✏️ Documentation | 文档 46 | 47 | * ✏️ 更新README中模板的名称 ([4bc38a3](https://gitee.com/fant-mini/uni-mini-router/commit/4bc38a33bb4ef4a1157348078ad1ee1d6b5250ef)) 48 | * ✏️ 增加联系方式 ([9d581bb](https://gitee.com/fant-mini/uni-mini-router/commit/9d581bba7b5b178eedd475a931081098d6dd1fbe)) 49 | * ✏️ 增加使用uni-parse-pages生成路由表的文档 ([9fb63af](https://gitee.com/fant-mini/uni-mini-router/commit/9fb63afc8e02246db5440df898a6ac398d551ad7)) 50 | * ✏️ 增加线上文档的地址 ([a14fd70](https://gitee.com/fant-mini/uni-mini-router/commit/a14fd70fffbc856d72c60d58a876628af36fe443)) 51 | 52 | ### [0.0.12](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.11...v0.0.12) (2023-05-10) 53 | 54 | 55 | ### ✏️ Documentation | 文档 56 | 57 | * ✏️ 增加支持AutoImport的文档,导出interfaces类型文件 ([a5f88f6](https://gitee.com/fant-mini/uni-mini-router/commit/a5f88f6785c9770eb8a1930f261ee9681b3f2c9b)) 58 | 59 | 60 | ### 🚀 Chore | 构建/工程依赖/工具 61 | 62 | * 🚀 新增.versionrc文件 ([4c09ce2](https://gitee.com/fant-mini/uni-mini-router/commit/4c09ce2ea9cbe154ad0996d10977d68873468862)) 63 | 64 | ### [0.0.11](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.10...v0.0.11) (2023-05-08) 65 | 66 | ### [0.0.10](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.9...v0.0.10) (2023-05-08) 67 | 68 | 69 | ### Bug Fixes 70 | 71 | * 🐛 修复全局后置守卫to和from都指向当前路由信息的问题 ([af71619](https://gitee.com/fant-mini/uni-mini-router/commit/af7161983768d69ca7ff420ffeb80e905af121ae)) 72 | * 🐛 修复全局前置导航守卫next无法指向跳转类型不同的页面的问题 ([53b51ac](https://gitee.com/fant-mini/uni-mini-router/commit/53b51acff62c0179a757b493ab0521d0e8a35811)) 73 | 74 | ### [0.0.9](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.8...v0.0.9) (2023-05-06) 75 | 76 | ### [0.0.8](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.7...v0.0.8) (2023-05-06) 77 | 78 | 79 | ### Bug Fixes 80 | 81 | * 🐛 修复未配置导航守卫时无法跳转的问题 ([a646f52](https://gitee.com/fant-mini/uni-mini-router/commit/a646f52b31285fad51d4f0c9e5b188711d140269)) 82 | 83 | ### [0.0.7](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.6...v0.0.7) (2023-04-27) 84 | 85 | 86 | ### Features 87 | 88 | * ✨ router.back方法入参改为可选参数 ([1924288](https://gitee.com/fant-mini/uni-mini-router/commit/1924288b9910685300f584380f5bf1ced6822490)) 89 | 90 | ### [0.0.6](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.5...v0.0.6) (2023-04-27) 91 | 92 | 93 | ### Features 94 | 95 | * ✨ 新增 useRoute 方法用于获取当前路由信息 ([def969e](https://gitee.com/fant-mini/uni-mini-router/commit/def969e2bf338ec3e0eeb6db45039d6a0d102258)) 96 | 97 | ### [0.0.5](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.4...v0.0.5) (2023-04-23) 98 | 99 | 100 | ### Features 101 | 102 | * ✨ 支持query和params传参,路由信息增加query和params ([dbe3222](https://gitee.com/fant-mini/uni-mini-router/commit/dbe322274e48f59e92332df38073d6d8f088a993)) 103 | 104 | ### [0.0.4](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.3...v0.0.4) (2023-04-04) 105 | 106 | ### [0.0.3](https://gitee.com/fant-mini/uni-read-pages-vite/compare/v0.0.2...v0.0.3) (2023-04-03) 107 | 108 | 109 | ### Bug Fixes 110 | 111 | * 🐛 修复使用async导致支付宝小程序页面白屏的问题 ([d2437fb](https://gitee.com/fant-mini/uni-read-pages-vite/commit/d2437fb41b505bb9ed4dc34db777a15f9fae4280)) 112 | 113 | ### [0.0.2](https://gitee.com/fant-mini/uni-read-pages-vite/compare/v0.0.1...v0.0.2) (2023-03-31) 114 | 115 | 116 | ### Features 117 | 118 | * ✨ 新增支持beforeEach和afterEach两个全局导航守卫 ([9691171](https://gitee.com/fant-mini/uni-read-pages-vite/commit/96911711605bb8d6522c042a5720fbacdb50c1d8)) 119 | 120 | ### 0.0.1 (2023-03-13) 121 | 122 | 123 | ### Features 124 | 125 | * ✨ 支持vue3+vite搭建的uni-app项目实现类vue-router的路由调用 ([a68ebe5](https://gitee.com/fant-mini/uni-read-pages-vite/commit/a68ebe5c58966143edc592e762f001e51d2510d8)) 126 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | 3 | 4 | ### [0.1.6](https://github.com/Moonofweisheng/uni-mini-router/compare/v0.1.5...v0.1.6) (2023-12-21) 5 | 6 | 7 | ### ✏️ Documentation | 文档 8 | 9 | * ✏️ 文档增加Algolia搜索 ([840a2aa](https://github.com/Moonofweisheng/uni-mini-router/commit/840a2aa6482d0064f344de9667e9907497611f20)) 10 | * ✏️ 增加链接uni-mini-router的起手项目 ([e83b7fe](https://github.com/Moonofweisheng/uni-mini-router/commit/e83b7fec436f2491f58b0372b5cb56c7371d6589)) 11 | 12 | 13 | ### 🐛 Bug Fixes | Bug 修复 14 | 15 | * 🐛 修复编译到快手小程序getRouteByPath因为路径匹配错误异常的情况 ([40ee469](https://github.com/Moonofweisheng/uni-mini-router/commit/40ee469311174b85adec3c850a2246a8cbd4c660)), closes [#8](https://github.com/Moonofweisheng/uni-mini-router/issues/8) 16 | 17 | ### [0.1.5](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.4...v0.1.5) (2023-10-23) 18 | 19 | 20 | ### ✏️ Documentation | 文档 21 | 22 | * ✏️ 更新文档地址 ([f19de73](https://gitee.com/fant-mini/uni-mini-router/commit/f19de73ca0e76747a07f8fb2b997f8defbc29587)) 23 | * ✏️ 文档建站 ([f3c6513](https://gitee.com/fant-mini/uni-mini-router/commit/f3c6513cb047241a0992e2c10a0405f78d9c3154)) 24 | * ✏️ 移除文档中的不可用图片 ([ac3b93b](https://gitee.com/fant-mini/uni-mini-router/commit/ac3b93b48ed028752085c013c358b56b4d328c45)) 25 | * ✏️ 增加相关链接 ([c03a7e0](https://gitee.com/fant-mini/uni-mini-router/commit/c03a7e06fea6b691df831dafee77f41b1a9d0f5d)) 26 | * ✏️ README中增加显示文档链接 ([21e4ce1](https://gitee.com/fant-mini/uni-mini-router/commit/21e4ce19368f1cc019154e8f545db3a43976c902)) 27 | 28 | ### [0.1.4](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.3...v0.1.4) (2023-08-09) 29 | 30 | 31 | ### ✏️ Documentation | 文档 32 | 33 | * ✏️ 增加联系方式 ([271c3db](https://gitee.com/fant-mini/uni-mini-router/commit/271c3db37fe4c95444d1f3676f8ea7b8948b50d0)) 34 | 35 | 36 | ### 🐛 Bug Fixes | Bug 修复 37 | 38 | * 🐛 修复前置导航守卫H5端打包后不执行的问题 ([13a1c11](https://gitee.com/fant-mini/uni-mini-router/commit/13a1c1180c9d4f53486fe275dd01071a1fa3240b)) 39 | 40 | ### [0.1.3](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.2...v0.1.3) (2023-07-07) 41 | 42 | 43 | ### 🐛 Bug Fixes | Bug 修复 44 | 45 | * 🐛 修复前置导航守卫非async时失效的问题 ([024ea1e](https://gitee.com/fant-mini/uni-mini-router/commit/024ea1e00b2257a5a6cd1d0ac20b22aa9b2095bf)) 46 | 47 | ### [0.1.2](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.1...v0.1.2) (2023-07-06) 48 | 49 | 50 | ### 🐛 Bug Fixes | Bug 修复 51 | 52 | * 🐛 修复在前置导航守卫中使用async/await导致无法跳转的问题 ([f385b9e](https://gitee.com/fant-mini/uni-mini-router/commit/f385b9e5558a7174de05174031666574870282d4)) 53 | 54 | ### [0.1.1](https://gitee.com/fant-mini/uni-mini-router/compare/v0.1.0...v0.1.1) (2023-05-31) 55 | 56 | 57 | ### 🐛 Bug Fixes | Bug 修复 58 | 59 | * 🐛 修复当前路由信息修改后会影响路由表信息的问题 ([c8f076e](https://gitee.com/fant-mini/uni-mini-router/commit/c8f076e0cd41f26788d2f8f76fda18eed8fd759c)) 60 | 61 | ## [0.1.0](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.12...v0.1.0) (2023-05-31) 62 | 63 | 64 | ### ✨ Features | 新功能 65 | 66 | * ✨ 优化 useRoute 的取值逻辑,新增在onShow周期更新route的逻辑 ([3b6bb8e](https://gitee.com/fant-mini/uni-mini-router/commit/3b6bb8e776a35872f0261c78482f9bf2e00e4f87)) 67 | 68 | 69 | ### ✏️ Documentation | 文档 70 | 71 | * ✏️ 更新README中模板的名称 ([4bc38a3](https://gitee.com/fant-mini/uni-mini-router/commit/4bc38a33bb4ef4a1157348078ad1ee1d6b5250ef)) 72 | * ✏️ 增加联系方式 ([9d581bb](https://gitee.com/fant-mini/uni-mini-router/commit/9d581bba7b5b178eedd475a931081098d6dd1fbe)) 73 | * ✏️ 增加使用uni-parse-pages生成路由表的文档 ([9fb63af](https://gitee.com/fant-mini/uni-mini-router/commit/9fb63afc8e02246db5440df898a6ac398d551ad7)) 74 | * ✏️ 增加线上文档的地址 ([a14fd70](https://gitee.com/fant-mini/uni-mini-router/commit/a14fd70fffbc856d72c60d58a876628af36fe443)) 75 | 76 | ### [0.0.12](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.11...v0.0.12) (2023-05-10) 77 | 78 | 79 | ### ✏️ Documentation | 文档 80 | 81 | * ✏️ 增加支持AutoImport的文档,导出interfaces类型文件 ([a5f88f6](https://gitee.com/fant-mini/uni-mini-router/commit/a5f88f6785c9770eb8a1930f261ee9681b3f2c9b)) 82 | 83 | 84 | ### 🚀 Chore | 构建/工程依赖/工具 85 | 86 | * 🚀 新增.versionrc文件 ([4c09ce2](https://gitee.com/fant-mini/uni-mini-router/commit/4c09ce2ea9cbe154ad0996d10977d68873468862)) 87 | 88 | ### [0.0.11](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.10...v0.0.11) (2023-05-08) 89 | 90 | ### [0.0.10](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.9...v0.0.10) (2023-05-08) 91 | 92 | 93 | ### Bug Fixes 94 | 95 | * 🐛 修复全局后置守卫to和from都指向当前路由信息的问题 ([af71619](https://gitee.com/fant-mini/uni-mini-router/commit/af7161983768d69ca7ff420ffeb80e905af121ae)) 96 | * 🐛 修复全局前置导航守卫next无法指向跳转类型不同的页面的问题 ([53b51ac](https://gitee.com/fant-mini/uni-mini-router/commit/53b51acff62c0179a757b493ab0521d0e8a35811)) 97 | 98 | ### [0.0.9](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.8...v0.0.9) (2023-05-06) 99 | 100 | ### [0.0.8](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.7...v0.0.8) (2023-05-06) 101 | 102 | 103 | ### Bug Fixes 104 | 105 | * 🐛 修复未配置导航守卫时无法跳转的问题 ([a646f52](https://gitee.com/fant-mini/uni-mini-router/commit/a646f52b31285fad51d4f0c9e5b188711d140269)) 106 | 107 | ### [0.0.7](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.6...v0.0.7) (2023-04-27) 108 | 109 | 110 | ### Features 111 | 112 | * ✨ router.back方法入参改为可选参数 ([1924288](https://gitee.com/fant-mini/uni-mini-router/commit/1924288b9910685300f584380f5bf1ced6822490)) 113 | 114 | ### [0.0.6](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.5...v0.0.6) (2023-04-27) 115 | 116 | 117 | ### Features 118 | 119 | * ✨ 新增 useRoute 方法用于获取当前路由信息 ([def969e](https://gitee.com/fant-mini/uni-mini-router/commit/def969e2bf338ec3e0eeb6db45039d6a0d102258)) 120 | 121 | ### [0.0.5](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.4...v0.0.5) (2023-04-23) 122 | 123 | 124 | ### Features 125 | 126 | * ✨ 支持query和params传参,路由信息增加query和params ([dbe3222](https://gitee.com/fant-mini/uni-mini-router/commit/dbe322274e48f59e92332df38073d6d8f088a993)) 127 | 128 | ### [0.0.4](https://gitee.com/fant-mini/uni-mini-router/compare/v0.0.3...v0.0.4) (2023-04-04) 129 | 130 | ### [0.0.3](https://gitee.com/fant-mini/uni-read-pages-vite/compare/v0.0.2...v0.0.3) (2023-04-03) 131 | 132 | 133 | ### Bug Fixes 134 | 135 | * 🐛 修复使用async导致支付宝小程序页面白屏的问题 ([d2437fb](https://gitee.com/fant-mini/uni-read-pages-vite/commit/d2437fb41b505bb9ed4dc34db777a15f9fae4280)) 136 | 137 | ### [0.0.2](https://gitee.com/fant-mini/uni-read-pages-vite/compare/v0.0.1...v0.0.2) (2023-03-31) 138 | 139 | 140 | ### Features 141 | 142 | * ✨ 新增支持beforeEach和afterEach两个全局导航守卫 ([9691171](https://gitee.com/fant-mini/uni-read-pages-vite/commit/96911711605bb8d6522c042a5720fbacdb50c1d8)) 143 | 144 | ### 0.0.1 (2023-03-13) 145 | 146 | 147 | ### Features 148 | 149 | * ✨ 支持vue3+vite搭建的uni-app项目实现类vue-router的路由调用 ([a68ebe5](https://gitee.com/fant-mini/uni-read-pages-vite/commit/a68ebe5c58966143edc592e762f001e51d2510d8)) 150 | -------------------------------------------------------------------------------- /src/router/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/ban-types */ 2 | /* 3 | * @Author: 徐庆凯 4 | * @Date: 2023-03-13 15:56:28 5 | * @LastEditTime: 2023-12-21 21:37:34 6 | * @LastEditors: weisheng 7 | * @Description: 8 | * @FilePath: \uni-mini-router\src\router\index.ts 9 | * 记得注释 10 | */ 11 | 12 | import { 13 | AfterEachGuard, 14 | BeforeEachGuard, 15 | HookType, 16 | NavMethod, 17 | NAVTYPE, 18 | NavTypeEnum, 19 | NextRouteBackLocation, 20 | NextRouteLocationRaw, 21 | Route, 22 | RouteLocationRaw, 23 | Router 24 | } from '../interfaces' 25 | 26 | import { beautifyUrl, getUrlParams, queryStringify, setUrlParams } from '../utils' 27 | 28 | // 保留uni默认的NavMethod 29 | const navMethods: Record = { 30 | navigateTo: uni.navigateTo, 31 | redirectTo: uni.redirectTo, 32 | reLaunch: uni.reLaunch, 33 | switchTab: uni.switchTab, 34 | navigateBack: uni.navigateBack 35 | } 36 | 37 | /** 38 | * 跳转至指定路由 39 | * @param to 目标路径 40 | * @param router router实例 41 | * @param navType 跳转类型 42 | * @returns 43 | */ 44 | export function navjump(to: RouteLocationRaw, router: Router, navType: NAVTYPE) { 45 | const url: string = getRoutePath(to, router) 46 | switch (navType) { 47 | case 'push': 48 | navMethods.navigateTo({ url: url }) 49 | break 50 | case 'replace': 51 | navMethods.redirectTo({ url: url }) 52 | break 53 | case 'pushTab': 54 | navMethods.switchTab({ url: url }) 55 | break 56 | case 'replaceAll': 57 | navMethods.reLaunch({ url: url }) 58 | break 59 | default: 60 | throw new Error('无效的路由类型,请确保提供正确的路由类型') 61 | // throw new Error('Invalid route type provided. Please ensure the provided route is of the correct type.') 62 | } 63 | return 64 | } 65 | 66 | /** 67 | * 获取目标路径 68 | * @param to 目标页面 69 | * @param router 70 | * @returns 71 | */ 72 | export function getRoutePath(to: RouteLocationRaw, router: Router): string { 73 | let url: string = '' // 路径 74 | let query: Record = {} 75 | if (typeof to === 'string') { 76 | url = to 77 | } else { 78 | if ((to as any).name) { 79 | // 通过name匹配路由 80 | const route = router.routes.find((item: { name: string }) => { 81 | return item.name === (to as any).name 82 | }) 83 | if (route && route.path) { 84 | url = route.path 85 | } else { 86 | throw new Error('您正在尝试访问的路由未在路由表中定义。请检查您的路由配置。') 87 | // throw new Error('The route you are trying to access is not defined in the routing table. Please check your routing configuration.') 88 | } 89 | query = (to as any).params 90 | } else if ((to as any).path) { 91 | url = beautifyUrl(`/${(to as any).path.split('?')[0]}`) 92 | query = { ...getUrlParams((to as any).path), ...((to as any).query || {}) } 93 | } 94 | if (query) { 95 | query = queryStringify(query) 96 | url = setUrlParams(url, query) 97 | } 98 | } 99 | return url 100 | } 101 | 102 | /** 103 | * 获取当前页面 104 | * @returns 当前页面 105 | */ 106 | export function getCurrentPage() { 107 | const pages = getCurrentPages() 108 | return pages.length > 0 ? pages[pages.length - 1] : undefined 109 | } 110 | 111 | /** 112 | * 保存路由信息到路由实例 113 | * @param router 路由实例 114 | * @param query 路由参数 115 | * @returns 116 | */ 117 | export function saveCurrRouteByCurrPage(router: Router) { 118 | router.route.value = getCurrentPageRoute(router) 119 | } 120 | 121 | /** 122 | * 获取当前页面的路由信息 123 | * @param router router实例 124 | * @returns 125 | */ 126 | export function getCurrentPageRoute(router: Router): Route { 127 | const page: any = getCurrentPage() 128 | if (!page || !page.route || !router.routes) { 129 | return 130 | } 131 | const currRoute: Route = getRouteByPath(`/${page.route}`, router) 132 | if (page.$page) { 133 | currRoute.fullPath = page.$page.fullPath ? page.$page.fullPath : '' 134 | currRoute.query = page.$page.fullPath ? getUrlParams(page.$page.fullPath) : {} 135 | currRoute.params = page.$page.fullPath ? getUrlParams(page.$page.fullPath) : {} 136 | } 137 | 138 | return currRoute 139 | } 140 | 141 | /** 142 | * 通过页面路路径寻找路由信息 143 | * @param path 页面路径 144 | * @param router 路由实例 145 | * @returns 路由信息 146 | */ 147 | export function getRouteByPath(path: string, router: Router): Route { 148 | path = beautifyUrl(path.split('?')[0]) 149 | const route: Route = router.routes.find((route: Route) => { 150 | return route.path === path || route.aliasPath === path 151 | }) 152 | return JSON.parse(JSON.stringify(route)) 153 | } 154 | 155 | /** 156 | * 注册守卫钩子 157 | * @param router 路由实例 158 | * @param hookType 钩子类型 159 | * @param userGuard 守卫 160 | */ 161 | export function registerEachHooks(router: Router, hookType: HookType, userGuard: BeforeEachGuard | AfterEachGuard) { 162 | router.guardHooks[hookType] = [userGuard as any] 163 | } 164 | // 保留uni默认的NavMethod 165 | const oldMethods: Record = { 166 | navigateTo: uni.navigateTo, 167 | redirectTo: uni.redirectTo, 168 | reLaunch: uni.reLaunch, 169 | switchTab: uni.switchTab, 170 | navigateBack: uni.navigateBack 171 | } 172 | 173 | /** 174 | * 重写uni路由相关事件 175 | */ 176 | export function rewriteNavMethod(router: Router) { 177 | NavMethod.forEach((name) => { 178 | navMethods[name] = function (options: any) { 179 | if (name === 'navigateBack') { 180 | oldMethods[name](options) 181 | } else { 182 | if (router.guardHooks.beforeHooks && router.guardHooks.beforeHooks[0]) { 183 | const to: Route = getRouteByPath(options.url, router) 184 | guardToPromiseFn(router.guardHooks.beforeHooks[0], to, router.route.value) 185 | .then((resp) => { 186 | if (resp === true) { 187 | oldMethods[name](options) 188 | } else { 189 | if (typeof resp === 'string') { 190 | const url: string = getRoutePath(resp, router) 191 | oldMethods[name]({ url: url }) 192 | } else if ((resp as NextRouteBackLocation).navType === 'back') { 193 | oldMethods['navigateBack'](resp) 194 | } else { 195 | const url: string = getRoutePath(resp as RouteLocationRaw, router) 196 | oldMethods[resp.navType ? NavTypeEnum[resp.navType] : name]({ url: url }) 197 | } 198 | } 199 | }) 200 | .catch((error) => { 201 | throw error 202 | }) 203 | } else { 204 | oldMethods[name](options) 205 | } 206 | } 207 | } 208 | }) 209 | } 210 | 211 | /** 212 | * 用Promise处理守卫方法 213 | * @param guard 守卫 214 | * @param to 目标路由 215 | * @param from 来源路由 216 | * @returns 217 | */ 218 | export function guardToPromiseFn(guard: BeforeEachGuard, to: Route, from: Route) { 219 | return new Promise((reslove, reject) => { 220 | const next: ((rule?: NextRouteLocationRaw | boolean) => void) | any = (rule?: NextRouteLocationRaw | boolean) => { 221 | next._called = true 222 | if (rule === false) { 223 | reject({}) 224 | } else if (rule === undefined || rule === true) { 225 | reslove(true) 226 | } else { 227 | reslove(rule) 228 | } 229 | } 230 | const guardReturn = guard.call(undefined, to, from, next) 231 | let guardCall = Promise.resolve(guardReturn) 232 | if (guard.length < 3) guardCall = guardCall.then(next) 233 | if (guard.length > 2) { 234 | const message = `The "next" callback was never called inside of ${ 235 | guard.name ? '"' + guard.name + '"' : '' 236 | }:\n${guard.toString()}\n. If you are returning a value instead of calling "next", make sure to remove the "next" parameter from your function.` 237 | if (guardReturn !== null && typeof guardReturn === 'object' && 'then' in guardReturn!) { 238 | guardCall = guardCall.then((resolvedValue) => { 239 | if (!next._called) { 240 | console.warn(message) 241 | return Promise.reject(new Error('Invalid navigation guard')) 242 | } 243 | return resolvedValue 244 | }) 245 | } else { 246 | if (!next._called) { 247 | console.warn(message) 248 | reject(new Error('Invalid navigation guard')) 249 | return 250 | } 251 | } 252 | } 253 | guardCall.catch((err) => reject(err)) 254 | }) 255 | } 256 | --------------------------------------------------------------------------------