[>
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 | | {{donor.name}} |
23 | {{donor.message}} |
24 | {{donor.link}} |
25 |
26 |
27 |
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 |
9 |
14 |
15 |
23 |
31 |
32 |
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 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
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 |
2 |
3 |
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 |
--------------------------------------------------------------------------------