Commit c303ec1a23c4b1fbad4fbda9007af2147dc327e2
1 parent
7bfe5f75
refactor: refactor route
Showing
84 changed files
with
1567 additions
and
1524 deletions
.github/workflows/deploy.yml
0 → 100644
1 | +name: deploy | ||
2 | + | ||
3 | +on: | ||
4 | + push: | ||
5 | + branches: | ||
6 | + - main | ||
7 | + | ||
8 | +jobs: | ||
9 | + build-deploy: | ||
10 | + runs-on: ubuntu-latest | ||
11 | + | ||
12 | + steps: | ||
13 | + - uses: actions/checkout@v1 | ||
14 | + - run: npm install | ||
15 | + - run: npm run build | ||
16 | + | ||
17 | + - name: Deploy | ||
18 | + uses: peaceiris/actions-gh-pages@v2.5.0 | ||
19 | + env: | ||
20 | + ACTIONS_DEPLOY_KEY: ${{secrets.ACTIONS_DEPLOY_KEY}} | ||
21 | + PUBLISH_BRANCH: gh-pages | ||
22 | + PUBLISH_DIR: dist |
.vscode/launch.json
1 | { | 1 | { |
2 | "version": "0.2.0", | 2 | "version": "0.2.0", |
3 | "configurations": [ | 3 | "configurations": [ |
4 | - // node环境调试当前激活编辑器ts/js代码 | ||
5 | { | 4 | { |
6 | - "type": "node", | 5 | + "type": "chrome", |
7 | "request": "launch", | 6 | "request": "launch", |
8 | - "name": "file", | ||
9 | - "cwd": "${workspaceFolder}", | ||
10 | - "program": "${file}", | ||
11 | - // .vscode 目录又不认识了??? | ||
12 | - "preLaunchTask": "tsc: 监视 - build/tsconfig.json", // cn | ||
13 | - // "preLaunchTask": "tsc: watch - build/tsconfig.json", // en | ||
14 | - "outFiles": ["${workspaceFolder}/compile/**/*.js"] | ||
15 | - // "args": ["--experimental-modules", "--loader", "./loader.mjs"] | 7 | + "name": "Launch Chrome", |
8 | + "url": "http://localhost:3100", | ||
9 | + "webRoot": "${workspaceFolder}/src", | ||
10 | + "sourceMaps": true | ||
16 | }, | 11 | }, |
17 | - // 调试开发环境脚本 | ||
18 | - { | ||
19 | - "type": "node", | ||
20 | - "request": "launch", | ||
21 | - "name": "dev", | ||
22 | - // "stopOnEntry": true, | ||
23 | - "cwd": "${workspaceFolder}", | ||
24 | - "program": "${workspaceFolder}/node_modules/@vue/cli-service/bin/vue-cli-service.js", | ||
25 | - "args": ["serve", "--open"] | ||
26 | - }, | ||
27 | - // 调试生产环境脚本 | ||
28 | - { | ||
29 | - "type": "node", | ||
30 | - "request": "launch", | ||
31 | - "name": "build", | ||
32 | - // "stopOnEntry": true, | ||
33 | - "cwd": "${workspaceFolder}", | ||
34 | - "program": "${workspaceFolder}/node_modules/@vue/cli-service/bin/vue-cli-service.js", | ||
35 | - "args": ["build"] | ||
36 | - }, | ||
37 | - // 调试单元测试脚本 | ||
38 | - { | ||
39 | - "type": "node", | ||
40 | - "request": "launch", | ||
41 | - "name": "test:unit", | ||
42 | - // "stopOnEntry": true, | ||
43 | - "cwd": "${workspaceFolder}", | ||
44 | - "program": "${workspaceFolder}/node_modules/@vue/cli-service/bin/vue-cli-service.js", | ||
45 | - "args": ["test:unit", "--detectOpenHandles"] | ||
46 | - } | ||
47 | ] | 12 | ] |
48 | } | 13 | } |
.vscode/settings.json
@@ -163,12 +163,6 @@ | @@ -163,12 +163,6 @@ | ||
163 | "[typescriptreact]": { | 163 | "[typescriptreact]": { |
164 | "editor.defaultFormatter": "esbenp.prettier-vscode" | 164 | "editor.defaultFormatter": "esbenp.prettier-vscode" |
165 | }, | 165 | }, |
166 | - "[json]": { | ||
167 | - "editor.defaultFormatter": "vscode.json-language-features" | ||
168 | - }, | ||
169 | - "[jsonc]": { | ||
170 | - "editor.defaultFormatter": "vscode.json-language-features" | ||
171 | - }, | ||
172 | "[html]": { | 166 | "[html]": { |
173 | "editor.defaultFormatter": "esbenp.prettier-vscode" | 167 | "editor.defaultFormatter": "esbenp.prettier-vscode" |
174 | }, | 168 | }, |
@@ -198,5 +192,8 @@ | @@ -198,5 +192,8 @@ | ||
198 | "ts" | 192 | "ts" |
199 | ], | 193 | ], |
200 | "i18n-ally.sourceLanguage": "zh", | 194 | "i18n-ally.sourceLanguage": "zh", |
201 | - "i18n-ally.enabledFrameworks":["vue","react"] | 195 | + "i18n-ally.enabledFrameworks": [ |
196 | + "vue", | ||
197 | + "react" | ||
198 | + ] | ||
202 | } | 199 | } |
203 | \ No newline at end of file | 200 | \ No newline at end of file |
CHANGELOG.zh_CN.md
1 | ## Wip | 1 | ## Wip |
2 | 2 | ||
3 | +## (破坏性更新) Breaking changes | ||
4 | + | ||
5 | +- 路由重构, 不再支持以前的格式。改为支持 vue-router 最初的默认结构,具体格式可以参考示例更改。实现多级路由缓存,不再将路由转化为 2 级。 | ||
6 | +- 重构面包屑,使用 antd 的面包屑组件。之前的组件已删除 | ||
7 | + | ||
3 | ### ✨ Features | 8 | ### ✨ Features |
4 | 9 | ||
5 | - 还原 antdv 默认 loading,重构 `Loading` 组件,增加`useLoading`和`v-loading`指令。并增加示例 | 10 | - 还原 antdv 默认 loading,重构 `Loading` 组件,增加`useLoading`和`v-loading`指令。并增加示例 |
6 | - i18n 支持 vscode `i18n-ally`插件 | 11 | - i18n 支持 vscode `i18n-ally`插件 |
12 | +- 新增多级路由缓存示例 | ||
7 | 13 | ||
8 | ### 🎫 Chores | 14 | ### 🎫 Chores |
9 | 15 | ||
10 | - 首屏 loading 修改 | 16 | - 首屏 loading 修改 |
11 | 17 | ||
18 | +### 🐛 Bug Fixes | ||
19 | + | ||
20 | +-修复表格 i18n 错误 | ||
21 | + | ||
12 | ## 2.0.0-rc.12 (2020-11-30) | 22 | ## 2.0.0-rc.12 (2020-11-30) |
13 | 23 | ||
14 | ## (破坏性更新) Breaking changes | 24 | ## (破坏性更新) Breaking changes |
build/vite/plugin/transform/dynamic-import/index.ts
@@ -17,8 +17,8 @@ const dynamicImportTransform = function (enableDynamicImport: boolean): Transfor | @@ -17,8 +17,8 @@ const dynamicImportTransform = function (enableDynamicImport: boolean): Transfor | ||
17 | test({ path }) { | 17 | test({ path }) { |
18 | // Only convert the file | 18 | // Only convert the file |
19 | return ( | 19 | return ( |
20 | - path.includes('/src/utils/helper/dynamicImport.ts') || | ||
21 | - path.includes(`\\src\\utils\\helper\\dynamicImport.ts`) | 20 | + path.includes('/src/router/helper/dynamicImport.ts') || |
21 | + path.includes(`\\src\\router\\helper\\dynamicImport.ts`) | ||
22 | ); | 22 | ); |
23 | }, | 23 | }, |
24 | transform({ code }) { | 24 | transform({ code }) { |
mock/sys/menu.ts
1 | import { resultSuccess } from '../_util'; | 1 | import { resultSuccess } from '../_util'; |
2 | import { MockMethod } from 'vite-plugin-mock'; | 2 | import { MockMethod } from 'vite-plugin-mock'; |
3 | 3 | ||
4 | +// single | ||
4 | const dashboardRoute = { | 5 | const dashboardRoute = { |
5 | - path: '/dashboard', | ||
6 | - name: 'Dashboard', | ||
7 | - component: 'PAGE_LAYOUT', | ||
8 | - redirect: '/dashboard/welcome', | 6 | + path: '/home', |
7 | + name: 'Home', | ||
8 | + component: '/dashboard/welcome/index', | ||
9 | meta: { | 9 | meta: { |
10 | + title: 'routes.dashboard.welcome', | ||
11 | + affix: true, | ||
10 | icon: 'ant-design:home-outlined', | 12 | icon: 'ant-design:home-outlined', |
11 | - title: 'Dashboard', | ||
12 | }, | 13 | }, |
13 | - children: [ | ||
14 | - { | ||
15 | - path: '/welcome', | ||
16 | - name: 'Welcome', | ||
17 | - component: '/dashboard/welcome/index', | ||
18 | - meta: { | ||
19 | - title: '欢迎页', | ||
20 | - affix: true, | ||
21 | - }, | ||
22 | - }, | ||
23 | - ], | ||
24 | }; | 14 | }; |
25 | 15 | ||
26 | const frontRoute = { | 16 | const frontRoute = { |
27 | - path: '/front', | 17 | + path: 'front', |
28 | name: 'PermissionFrontDemo', | 18 | name: 'PermissionFrontDemo', |
29 | meta: { | 19 | meta: { |
30 | - title: '基于前端权限', | 20 | + title: 'routes.demo.permission.front', |
31 | }, | 21 | }, |
32 | children: [ | 22 | children: [ |
33 | { | 23 | { |
@@ -35,7 +25,7 @@ const frontRoute = { | @@ -35,7 +25,7 @@ const frontRoute = { | ||
35 | name: 'FrontPageAuth', | 25 | name: 'FrontPageAuth', |
36 | component: '/demo/permission/front/index', | 26 | component: '/demo/permission/front/index', |
37 | meta: { | 27 | meta: { |
38 | - title: '页面权限', | 28 | + title: 'routes.demo.permission.frontPage', |
39 | }, | 29 | }, |
40 | }, | 30 | }, |
41 | { | 31 | { |
@@ -43,7 +33,7 @@ const frontRoute = { | @@ -43,7 +33,7 @@ const frontRoute = { | ||
43 | name: 'FrontBtnAuth', | 33 | name: 'FrontBtnAuth', |
44 | component: '/demo/permission/front/Btn', | 34 | component: '/demo/permission/front/Btn', |
45 | meta: { | 35 | meta: { |
46 | - title: '按钮权限', | 36 | + title: 'routes.demo.permission.frontBtn', |
47 | }, | 37 | }, |
48 | }, | 38 | }, |
49 | { | 39 | { |
@@ -51,7 +41,7 @@ const frontRoute = { | @@ -51,7 +41,7 @@ const frontRoute = { | ||
51 | name: 'FrontAuthPageA', | 41 | name: 'FrontAuthPageA', |
52 | component: '/demo/permission/front/AuthPageA', | 42 | component: '/demo/permission/front/AuthPageA', |
53 | meta: { | 43 | meta: { |
54 | - title: '权限测试页A', | 44 | + title: 'routes.demo.permission.frontTestA', |
55 | }, | 45 | }, |
56 | }, | 46 | }, |
57 | { | 47 | { |
@@ -59,24 +49,25 @@ const frontRoute = { | @@ -59,24 +49,25 @@ const frontRoute = { | ||
59 | name: 'FrontAuthPageB', | 49 | name: 'FrontAuthPageB', |
60 | component: '/demo/permission/front/AuthPageB', | 50 | component: '/demo/permission/front/AuthPageB', |
61 | meta: { | 51 | meta: { |
62 | - title: '权限测试页B', | 52 | + title: 'routes.demo.permission.frontTestB', |
63 | }, | 53 | }, |
64 | }, | 54 | }, |
65 | ], | 55 | ], |
66 | }; | 56 | }; |
67 | const backRoute = { | 57 | const backRoute = { |
68 | - path: '/back', | 58 | + path: 'back', |
69 | name: 'PermissionBackDemo', | 59 | name: 'PermissionBackDemo', |
70 | meta: { | 60 | meta: { |
71 | - title: '基于后台权限', | 61 | + title: 'routes.demo.permission.back', |
72 | }, | 62 | }, |
63 | + | ||
73 | children: [ | 64 | children: [ |
74 | { | 65 | { |
75 | path: 'page', | 66 | path: 'page', |
76 | name: 'BackAuthPage', | 67 | name: 'BackAuthPage', |
77 | component: '/demo/permission/back/index', | 68 | component: '/demo/permission/back/index', |
78 | meta: { | 69 | meta: { |
79 | - title: '页面权限', | 70 | + title: 'routes.demo.permission.backPage', |
80 | }, | 71 | }, |
81 | }, | 72 | }, |
82 | { | 73 | { |
@@ -84,7 +75,7 @@ const backRoute = { | @@ -84,7 +75,7 @@ const backRoute = { | ||
84 | name: 'BackAuthBtn', | 75 | name: 'BackAuthBtn', |
85 | component: '/demo/permission/back/Btn', | 76 | component: '/demo/permission/back/Btn', |
86 | meta: { | 77 | meta: { |
87 | - title: '按钮权限', | 78 | + title: 'routes.demo.permission.backBtn', |
88 | }, | 79 | }, |
89 | }, | 80 | }, |
90 | ], | 81 | ], |
@@ -92,11 +83,11 @@ const backRoute = { | @@ -92,11 +83,11 @@ const backRoute = { | ||
92 | const authRoute = { | 83 | const authRoute = { |
93 | path: '/permission', | 84 | path: '/permission', |
94 | name: 'Permission', | 85 | name: 'Permission', |
95 | - component: 'PAGE_LAYOUT', | 86 | + component: 'LAYOUT', |
96 | redirect: '/permission/front/page', | 87 | redirect: '/permission/front/page', |
97 | meta: { | 88 | meta: { |
98 | - icon: 'ant-design:home-outlined', | ||
99 | - title: '权限管理', | 89 | + icon: 'carbon:user-role', |
90 | + title: 'routes.demo.permission.permission', | ||
100 | }, | 91 | }, |
101 | children: [frontRoute, backRoute], | 92 | children: [frontRoute, backRoute], |
102 | }; | 93 | }; |
@@ -104,14 +95,70 @@ const authRoute = { | @@ -104,14 +95,70 @@ const authRoute = { | ||
104 | const authRoute1 = { | 95 | const authRoute1 = { |
105 | path: '/permission', | 96 | path: '/permission', |
106 | name: 'Permission', | 97 | name: 'Permission', |
107 | - component: 'PAGE_LAYOUT', | 98 | + component: 'LAYOUT', |
108 | redirect: '/permission/front/page', | 99 | redirect: '/permission/front/page', |
109 | meta: { | 100 | meta: { |
110 | - icon: 'ant-design:home-outlined', | ||
111 | - title: '权限管理', | 101 | + icon: 'carbon:user-role', |
102 | + title: 'routes.demo.permission.permission', | ||
112 | }, | 103 | }, |
113 | children: [backRoute], | 104 | children: [backRoute], |
114 | }; | 105 | }; |
106 | + | ||
107 | +const levelRoute = { | ||
108 | + path: '/level', | ||
109 | + name: 'Level', | ||
110 | + component: 'LAYOUT', | ||
111 | + redirect: '/level/menu1/menu1-1', | ||
112 | + meta: { | ||
113 | + icon: 'carbon:user-role', | ||
114 | + title: 'routes.demo.level.level', | ||
115 | + }, | ||
116 | + | ||
117 | + children: [ | ||
118 | + { | ||
119 | + path: 'menu1', | ||
120 | + name: 'Menu1Demo', | ||
121 | + meta: { | ||
122 | + title: 'Menu1', | ||
123 | + }, | ||
124 | + children: [ | ||
125 | + { | ||
126 | + path: 'menu1-1', | ||
127 | + name: 'Menu11Demo', | ||
128 | + meta: { | ||
129 | + title: 'Menu1-1', | ||
130 | + }, | ||
131 | + children: [ | ||
132 | + { | ||
133 | + path: 'menu1-1-1', | ||
134 | + name: 'Menu111Demo', | ||
135 | + component: '/demo/level/Menu111', | ||
136 | + meta: { | ||
137 | + title: 'Menu111', | ||
138 | + }, | ||
139 | + }, | ||
140 | + ], | ||
141 | + }, | ||
142 | + { | ||
143 | + path: 'menu1-2', | ||
144 | + name: 'Menu12Demo', | ||
145 | + component: '/demo/level/Menu12', | ||
146 | + meta: { | ||
147 | + title: 'Menu1-2', | ||
148 | + }, | ||
149 | + }, | ||
150 | + ], | ||
151 | + }, | ||
152 | + { | ||
153 | + path: 'menu2', | ||
154 | + name: 'Menu2Demo', | ||
155 | + component: '/demo/level/Menu2', | ||
156 | + meta: { | ||
157 | + title: 'Menu2', | ||
158 | + }, | ||
159 | + }, | ||
160 | + ], | ||
161 | +}; | ||
115 | export default [ | 162 | export default [ |
116 | { | 163 | { |
117 | url: '/api/getMenuListById', | 164 | url: '/api/getMenuListById', |
@@ -120,10 +167,10 @@ export default [ | @@ -120,10 +167,10 @@ export default [ | ||
120 | response: ({ query }) => { | 167 | response: ({ query }) => { |
121 | const { id } = query; | 168 | const { id } = query; |
122 | if (!id || id === '1') { | 169 | if (!id || id === '1') { |
123 | - return resultSuccess([dashboardRoute, authRoute]); | 170 | + return resultSuccess([dashboardRoute, authRoute, levelRoute]); |
124 | } | 171 | } |
125 | if (id === '2') { | 172 | if (id === '2') { |
126 | - return resultSuccess([dashboardRoute, authRoute1]); | 173 | + return resultSuccess([dashboardRoute, authRoute1, levelRoute]); |
127 | } | 174 | } |
128 | }, | 175 | }, |
129 | }, | 176 | }, |
package.json
@@ -35,7 +35,7 @@ | @@ -35,7 +35,7 @@ | ||
35 | "qrcode": "^1.4.4", | 35 | "qrcode": "^1.4.4", |
36 | "sortablejs": "^1.12.0", | 36 | "sortablejs": "^1.12.0", |
37 | "vditor": "^3.7.0", | 37 | "vditor": "^3.7.0", |
38 | - "vue": "^3.0.3", | 38 | + "vue": "^3.0.4", |
39 | "vue-i18n": "^9.0.0-beta.8", | 39 | "vue-i18n": "^9.0.0-beta.8", |
40 | "vue-router": "^4.0.0-rc.6", | 40 | "vue-router": "^4.0.0-rc.6", |
41 | "vue-types": "^3.0.1", | 41 | "vue-types": "^3.0.1", |
@@ -47,7 +47,7 @@ | @@ -47,7 +47,7 @@ | ||
47 | "devDependencies": { | 47 | "devDependencies": { |
48 | "@commitlint/cli": "^11.0.0", | 48 | "@commitlint/cli": "^11.0.0", |
49 | "@commitlint/config-conventional": "^11.0.0", | 49 | "@commitlint/config-conventional": "^11.0.0", |
50 | - "@iconify/json": "^1.1.266", | 50 | + "@iconify/json": "^1.1.267", |
51 | "@ls-lint/ls-lint": "^1.9.2", | 51 | "@ls-lint/ls-lint": "^1.9.2", |
52 | "@purge-icons/generated": "^0.4.1", | 52 | "@purge-icons/generated": "^0.4.1", |
53 | "@types/echarts": "^4.9.2", | 53 | "@types/echarts": "^4.9.2", |
@@ -60,25 +60,25 @@ | @@ -60,25 +60,25 @@ | ||
60 | "@types/qrcode": "^1.3.5", | 60 | "@types/qrcode": "^1.3.5", |
61 | "@types/rollup-plugin-visualizer": "^2.6.0", | 61 | "@types/rollup-plugin-visualizer": "^2.6.0", |
62 | "@types/sortablejs": "^1.10.6", | 62 | "@types/sortablejs": "^1.10.6", |
63 | - "@types/yargs": "^15.0.10", | 63 | + "@types/yargs": "^15.0.11", |
64 | "@types/zxcvbn": "^4.4.0", | 64 | "@types/zxcvbn": "^4.4.0", |
65 | "@typescript-eslint/eslint-plugin": "^4.9.0", | 65 | "@typescript-eslint/eslint-plugin": "^4.9.0", |
66 | "@typescript-eslint/parser": "^4.9.0", | 66 | "@typescript-eslint/parser": "^4.9.0", |
67 | - "@vue/compiler-sfc": "^3.0.3", | 67 | + "@vue/compiler-sfc": "^3.0.4", |
68 | "@vuedx/typecheck": "^0.2.4-0", | 68 | "@vuedx/typecheck": "^0.2.4-0", |
69 | "@vuedx/typescript-plugin-vue": "^0.2.4-0", | 69 | "@vuedx/typescript-plugin-vue": "^0.2.4-0", |
70 | "autoprefixer": "^9.8.6", | 70 | "autoprefixer": "^9.8.6", |
71 | "commitizen": "^4.2.2", | 71 | "commitizen": "^4.2.2", |
72 | "conventional-changelog-cli": "^2.1.1", | 72 | "conventional-changelog-cli": "^2.1.1", |
73 | "conventional-changelog-custom-config": "^0.3.1", | 73 | "conventional-changelog-custom-config": "^0.3.1", |
74 | - "cross-env": "^7.0.2", | 74 | + "cross-env": "^7.0.3", |
75 | "dot-prop": "^6.0.1", | 75 | "dot-prop": "^6.0.1", |
76 | "dotenv": "^8.2.0", | 76 | "dotenv": "^8.2.0", |
77 | "eslint": "^7.14.0", | 77 | "eslint": "^7.14.0", |
78 | "eslint-config-prettier": "^6.15.0", | 78 | "eslint-config-prettier": "^6.15.0", |
79 | "eslint-plugin-prettier": "^3.1.4", | 79 | "eslint-plugin-prettier": "^3.1.4", |
80 | "eslint-plugin-vue": "^7.1.0", | 80 | "eslint-plugin-vue": "^7.1.0", |
81 | - "esno": "^0.2.4", | 81 | + "esno": "^0.3.0", |
82 | "fs-extra": "^9.0.1", | 82 | "fs-extra": "^9.0.1", |
83 | "globrex": "^0.1.2", | 83 | "globrex": "^0.1.2", |
84 | "husky": "^4.3.0", | 84 | "husky": "^4.3.0", |
src/components/Breadcrumb/index.ts deleted
100644 → 0
src/components/Breadcrumb/src/Breadcrumb.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div ref="breadcrumbRef" class="breadcrumb"> | ||
3 | - <slot /> | ||
4 | - </div> | ||
5 | -</template> | ||
6 | - | ||
7 | -<script lang="ts"> | ||
8 | - import { defineComponent, provide, ref } from 'vue'; | ||
9 | - import { propTypes } from '/@/utils/propTypes'; | ||
10 | - | ||
11 | - export default defineComponent({ | ||
12 | - name: 'Breadcrumb', | ||
13 | - props: { | ||
14 | - separator: propTypes.string.def('/'), | ||
15 | - separatorClass: propTypes.string, | ||
16 | - }, | ||
17 | - setup(props) { | ||
18 | - const breadcrumbRef = ref<Nullable<HTMLElement>>(null); | ||
19 | - | ||
20 | - provide('breadcrumb', props); | ||
21 | - | ||
22 | - return { | ||
23 | - breadcrumbRef, | ||
24 | - }; | ||
25 | - }, | ||
26 | - }); | ||
27 | -</script> | ||
28 | -<style lang="less"> | ||
29 | - @import (reference) '../../../design/index.less'; | ||
30 | - | ||
31 | - .breadcrumb { | ||
32 | - .unselect(); | ||
33 | - | ||
34 | - height: @header-height; | ||
35 | - padding-right: 20px; | ||
36 | - font-size: 13px; | ||
37 | - line-height: @header-height; | ||
38 | - // line-height: 1; | ||
39 | - | ||
40 | - &::after, | ||
41 | - &::before { | ||
42 | - display: table; | ||
43 | - content: ''; | ||
44 | - } | ||
45 | - | ||
46 | - &::after { | ||
47 | - clear: both; | ||
48 | - } | ||
49 | - | ||
50 | - &__separator { | ||
51 | - margin: 0 9px; | ||
52 | - font-weight: 700; | ||
53 | - color: @breadcrumb-item-normal-color; | ||
54 | - | ||
55 | - &[class*='icon'] { | ||
56 | - margin: 0 6px; | ||
57 | - font-weight: 400; | ||
58 | - } | ||
59 | - } | ||
60 | - | ||
61 | - &__item { | ||
62 | - float: left; | ||
63 | - } | ||
64 | - | ||
65 | - &__inner { | ||
66 | - color: @breadcrumb-item-normal-color; | ||
67 | - | ||
68 | - &.is-link, | ||
69 | - a { | ||
70 | - font-weight: 500; | ||
71 | - color: @text-color-base; | ||
72 | - text-decoration: none; | ||
73 | - transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); | ||
74 | - } | ||
75 | - | ||
76 | - a:hover, | ||
77 | - &.is-link:hover { | ||
78 | - color: @primary-color; | ||
79 | - cursor: pointer; | ||
80 | - } | ||
81 | - } | ||
82 | - | ||
83 | - &__item:last-child .breadcrumb__inner, | ||
84 | - &__item:last-child &__inner a, | ||
85 | - &__item:last-child &__inner a:hover, | ||
86 | - &__item:last-child &__inner:hover { | ||
87 | - font-weight: 400; | ||
88 | - color: @breadcrumb-item-normal-color; | ||
89 | - cursor: text; | ||
90 | - } | ||
91 | - | ||
92 | - &__item:last-child &__separator { | ||
93 | - display: none; | ||
94 | - } | ||
95 | - } | ||
96 | -</style> |
src/components/Breadcrumb/src/BreadcrumbItem.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <span class="breadcrumb__item"> | ||
3 | - <span ref="linkRef" :class="['breadcrumb__inner', to || isLink ? 'is-link' : '']"> | ||
4 | - <slot /> | ||
5 | - </span> | ||
6 | - <i v-if="separatorClass" class="breadcrumb__separator" :class="separatorClass"></i> | ||
7 | - <span v-else class="breadcrumb__separator">{{ separator }}</span> | ||
8 | - </span> | ||
9 | -</template> | ||
10 | - | ||
11 | -<script lang="ts"> | ||
12 | - import { defineComponent, inject, ref, onMounted, unref } from 'vue'; | ||
13 | - import { useRouter } from 'vue-router'; | ||
14 | - import { useEventListener } from '/@/hooks/event/useEventListener'; | ||
15 | - | ||
16 | - import { propTypes } from '/@/utils/propTypes'; | ||
17 | - | ||
18 | - export default defineComponent({ | ||
19 | - name: 'BreadcrumbItem', | ||
20 | - props: { | ||
21 | - to: propTypes.oneOfType([propTypes.string, propTypes.object]), | ||
22 | - replace: propTypes.bool, | ||
23 | - isLink: propTypes.bool, | ||
24 | - }, | ||
25 | - setup(props) { | ||
26 | - const linkRef = ref<Nullable<HTMLElement>>(null); | ||
27 | - | ||
28 | - const parent = inject('breadcrumb') as { | ||
29 | - separator: string; | ||
30 | - separatorClass: string; | ||
31 | - }; | ||
32 | - | ||
33 | - const { push, replace } = useRouter(); | ||
34 | - | ||
35 | - onMounted(() => { | ||
36 | - const link = unref(linkRef); | ||
37 | - if (!link) return; | ||
38 | - useEventListener({ | ||
39 | - el: link, | ||
40 | - listener: () => { | ||
41 | - const { to } = props; | ||
42 | - if (!props.to) return; | ||
43 | - props.replace ? replace(to) : push(to); | ||
44 | - }, | ||
45 | - name: 'click', | ||
46 | - wait: 0, | ||
47 | - }); | ||
48 | - }); | ||
49 | - | ||
50 | - return { | ||
51 | - linkRef, | ||
52 | - separator: parent.separator && parent.separator, | ||
53 | - separatorClass: parent.separatorClass && parent.separatorClass, | ||
54 | - }; | ||
55 | - }, | ||
56 | - }); | ||
57 | -</script> |
src/components/Menu/src/BasicMenu.tsx
@@ -36,6 +36,7 @@ import { getCurrentParentPath } from '/@/router/menus'; | @@ -36,6 +36,7 @@ import { getCurrentParentPath } from '/@/router/menus'; | ||
36 | 36 | ||
37 | import { basicProps } from './props'; | 37 | import { basicProps } from './props'; |
38 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 38 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
39 | +import { REDIRECT_NAME } from '/@/router/constant'; | ||
39 | export default defineComponent({ | 40 | export default defineComponent({ |
40 | name: 'BasicMenu', | 41 | name: 'BasicMenu', |
41 | props: basicProps, | 42 | props: basicProps, |
@@ -120,7 +121,7 @@ export default defineComponent({ | @@ -120,7 +121,7 @@ export default defineComponent({ | ||
120 | watch( | 121 | watch( |
121 | () => currentRoute.value.name, | 122 | () => currentRoute.value.name, |
122 | (name: string) => { | 123 | (name: string) => { |
123 | - if (name === 'Redirect') return; | 124 | + if (name === REDIRECT_NAME) return; |
124 | handleMenuChange(); | 125 | handleMenuChange(); |
125 | props.isHorizontal && appStore.getProjectConfig.menuSetting.split && getParentPath(); | 126 | props.isHorizontal && appStore.getProjectConfig.menuSetting.split && getParentPath(); |
126 | } | 127 | } |
src/components/Menu/src/hooks/useOpenKeys.ts
@@ -4,7 +4,7 @@ import type { MenuState } from '../types'; | @@ -4,7 +4,7 @@ import type { MenuState } from '../types'; | ||
4 | import type { Ref } from 'vue'; | 4 | import type { Ref } from 'vue'; |
5 | 5 | ||
6 | import { unref } from 'vue'; | 6 | import { unref } from 'vue'; |
7 | -import { getAllParentPath } from '/@/utils/helper/menuHelper'; | 7 | +import { getAllParentPath } from '/@/router/helper/menuHelper'; |
8 | import { es6Unique } from '/@/utils'; | 8 | import { es6Unique } from '/@/utils'; |
9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
10 | 10 |
src/components/Menu/src/hooks/useSearchInput.ts
@@ -5,7 +5,7 @@ import type { Ref } from 'vue'; | @@ -5,7 +5,7 @@ import type { Ref } from 'vue'; | ||
5 | import { isString } from '/@/utils/is'; | 5 | import { isString } from '/@/utils/is'; |
6 | import { unref } from 'vue'; | 6 | import { unref } from 'vue'; |
7 | import { es6Unique } from '/@/utils'; | 7 | import { es6Unique } from '/@/utils'; |
8 | -import { getAllParentPath } from '/@/utils/helper/menuHelper'; | 8 | +import { getAllParentPath } from '/@/router/helper/menuHelper'; |
9 | 9 | ||
10 | interface UseSearchInputOptions { | 10 | interface UseSearchInputOptions { |
11 | menuState: MenuState; | 11 | menuState: MenuState; |
src/components/Table/src/components/TableSetting.vue
@@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
33 | 33 | ||
34 | <Tooltip placement="top" v-if="getSetting.setting"> | 34 | <Tooltip placement="top" v-if="getSetting.setting"> |
35 | <template #title> | 35 | <template #title> |
36 | - <span>{{ t('settingColumn') }}</span> | 36 | + <span>{{ t('component.table.settingColumn') }}</span> |
37 | </template> | 37 | </template> |
38 | <Popover | 38 | <Popover |
39 | placement="bottomLeft" | 39 | placement="bottomLeft" |
@@ -58,9 +58,11 @@ | @@ -58,9 +58,11 @@ | ||
58 | v-model:checked="checkAll" | 58 | v-model:checked="checkAll" |
59 | @change="onCheckAllChange" | 59 | @change="onCheckAllChange" |
60 | > | 60 | > |
61 | - {{ t('settingColumnShow') }} | 61 | + {{ t('component.table.settingColumnShow') }} |
62 | </Checkbox> | 62 | </Checkbox> |
63 | - <a-button size="small" type="link" @click="reset"> {{ t('settingReset') }}</a-button> | 63 | + <a-button size="small" type="link" @click="reset"> |
64 | + {{ t('component.table.settingReset') }}</a-button | ||
65 | + > | ||
64 | </div> | 66 | </div> |
65 | </template> | 67 | </template> |
66 | <SettingOutlined /> | 68 | <SettingOutlined /> |
@@ -69,7 +71,7 @@ | @@ -69,7 +71,7 @@ | ||
69 | 71 | ||
70 | <Tooltip placement="top" v-if="getSetting.fullScreen"> | 72 | <Tooltip placement="top" v-if="getSetting.fullScreen"> |
71 | <template #title> | 73 | <template #title> |
72 | - <span>{{ t('settingFullScreen') }}</span> | 74 | + <span>{{ t('component.table.settingFullScreen') }}</span> |
73 | </template> | 75 | </template> |
74 | <FullscreenOutlined @click="handleFullScreen" v-if="!isFullscreenRef" /> | 76 | <FullscreenOutlined @click="handleFullScreen" v-if="!isFullscreenRef" /> |
75 | <FullscreenExitOutlined @click="handleFullScreen" v-else /> | 77 | <FullscreenExitOutlined @click="handleFullScreen" v-else /> |
src/components/registerGlobComp.ts
@@ -33,6 +33,7 @@ import { | @@ -33,6 +33,7 @@ import { | ||
33 | Empty, | 33 | Empty, |
34 | Avatar, | 34 | Avatar, |
35 | Menu, | 35 | Menu, |
36 | + Breadcrumb, | ||
36 | } from 'ant-design-vue'; | 37 | } from 'ant-design-vue'; |
37 | import { getApp } from '/@/setup/App'; | 38 | import { getApp } from '/@/setup/App'; |
38 | 39 | ||
@@ -55,6 +56,7 @@ export function registerGlobComp() { | @@ -55,6 +56,7 @@ export function registerGlobComp() { | ||
55 | getApp() | 56 | getApp() |
56 | .use(Select) | 57 | .use(Select) |
57 | .use(Alert) | 58 | .use(Alert) |
59 | + .use(Breadcrumb) | ||
58 | .use(Checkbox) | 60 | .use(Checkbox) |
59 | .use(DatePicker) | 61 | .use(DatePicker) |
60 | .use(Radio) | 62 | .use(Radio) |
src/design/transition/breadcrumb.less deleted
100644 → 0
1 | -.breadcrumb-enter-active, | ||
2 | -.breadcrumb-leave-active { | ||
3 | - transition: all 0.24s; | ||
4 | -} | ||
5 | - | ||
6 | -.breadcrumb-enter-from, | ||
7 | -.breadcrumb-leave-active { | ||
8 | - opacity: 0; | ||
9 | - transform: translateX(16px); | ||
10 | -} | ||
11 | - | ||
12 | -.breadcrumb-move { | ||
13 | - transition: all 0.38s; | ||
14 | -} | ||
15 | - | ||
16 | -.breadcrumb-leave-active { | ||
17 | - position: absolute; | ||
18 | -} |
src/design/transition/index.less
src/enums/pageEnum.ts
@@ -2,7 +2,7 @@ export enum PageEnum { | @@ -2,7 +2,7 @@ export enum PageEnum { | ||
2 | // basic login path | 2 | // basic login path |
3 | BASE_LOGIN = '/login', | 3 | BASE_LOGIN = '/login', |
4 | // basic home path | 4 | // basic home path |
5 | - BASE_HOME = '/dashboard', | 5 | + BASE_HOME = '/home', |
6 | // error page path | 6 | // error page path |
7 | ERROR_PAGE = '/exception', | 7 | ERROR_PAGE = '/exception', |
8 | // error log page path | 8 | // error log page path |
src/hooks/web/usePage.ts
1 | import { appStore } from '/@/store/modules/app'; | 1 | import { appStore } from '/@/store/modules/app'; |
2 | import type { RouteLocationRaw } from 'vue-router'; | 2 | import type { RouteLocationRaw } from 'vue-router'; |
3 | 3 | ||
4 | -import { useRouter } from 'vue-router'; | ||
5 | import { PageEnum } from '/@/enums/pageEnum'; | 4 | import { PageEnum } from '/@/enums/pageEnum'; |
6 | import { isString } from '/@/utils/is'; | 5 | import { isString } from '/@/utils/is'; |
7 | import { unref } from 'vue'; | 6 | import { unref } from 'vue'; |
8 | 7 | ||
8 | +import router from '/@/router'; | ||
9 | + | ||
9 | export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum }; | 10 | export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum }; |
10 | 11 | ||
11 | function handleError(e: Error) { | 12 | function handleError(e: Error) { |
@@ -18,7 +19,7 @@ function handleError(e: Error) { | @@ -18,7 +19,7 @@ function handleError(e: Error) { | ||
18 | 19 | ||
19 | // page switch | 20 | // page switch |
20 | export function useGo() { | 21 | export function useGo() { |
21 | - const { push, replace } = useRouter(); | 22 | + const { push, replace } = router; |
22 | function go(opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME, isReplace = false) { | 23 | function go(opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME, isReplace = false) { |
23 | if (!opt) return; | 24 | if (!opt) return; |
24 | if (isString(opt)) { | 25 | if (isString(opt)) { |
@@ -35,7 +36,7 @@ export function useGo() { | @@ -35,7 +36,7 @@ export function useGo() { | ||
35 | * @description: redo current page | 36 | * @description: redo current page |
36 | */ | 37 | */ |
37 | export const useRedo = () => { | 38 | export const useRedo = () => { |
38 | - const { push, currentRoute } = useRouter(); | 39 | + const { push, currentRoute } = router; |
39 | const { query, params } = currentRoute.value; | 40 | const { query, params } = currentRoute.value; |
40 | function redo() { | 41 | function redo() { |
41 | push({ | 42 | push({ |
src/hooks/web/usePermission.ts
@@ -7,13 +7,14 @@ import { userStore } from '/@/store/modules/user'; | @@ -7,13 +7,14 @@ import { userStore } from '/@/store/modules/user'; | ||
7 | import { useTabs } from './useTabs'; | 7 | import { useTabs } from './useTabs'; |
8 | 8 | ||
9 | import router, { resetRouter } from '/@/router'; | 9 | import router, { resetRouter } from '/@/router'; |
10 | -import { RootRoute } from '/@/router/routes'; | 10 | +// import { RootRoute } from '/@/router/routes'; |
11 | 11 | ||
12 | import { PermissionModeEnum } from '/@/enums/appEnum'; | 12 | import { PermissionModeEnum } from '/@/enums/appEnum'; |
13 | import { RoleEnum } from '/@/enums/roleEnum'; | 13 | import { RoleEnum } from '/@/enums/roleEnum'; |
14 | 14 | ||
15 | import { intersection } from 'lodash-es'; | 15 | import { intersection } from 'lodash-es'; |
16 | import { isArray } from '/@/utils/is'; | 16 | import { isArray } from '/@/utils/is'; |
17 | +import { tabStore } from '/@/store/modules/tab'; | ||
17 | 18 | ||
18 | // User permissions related operations | 19 | // User permissions related operations |
19 | export function usePermission() { | 20 | export function usePermission() { |
@@ -27,8 +28,7 @@ export function usePermission() { | @@ -27,8 +28,7 @@ export function usePermission() { | ||
27 | ? PermissionModeEnum.ROLE | 28 | ? PermissionModeEnum.ROLE |
28 | : PermissionModeEnum.BACK, | 29 | : PermissionModeEnum.BACK, |
29 | }); | 30 | }); |
30 | - resume(); | ||
31 | - // location.reload(); | 31 | + location.reload(); |
32 | } | 32 | } |
33 | 33 | ||
34 | /** | 34 | /** |
@@ -36,18 +36,15 @@ export function usePermission() { | @@ -36,18 +36,15 @@ export function usePermission() { | ||
36 | * @param id | 36 | * @param id |
37 | */ | 37 | */ |
38 | async function resume(id?: string | number) { | 38 | async function resume(id?: string | number) { |
39 | + tabStore.commitClearCache(); | ||
39 | resetRouter(); | 40 | resetRouter(); |
40 | const routes = await permissionStore.buildRoutesAction(id); | 41 | const routes = await permissionStore.buildRoutesAction(id); |
41 | routes.forEach((route) => { | 42 | routes.forEach((route) => { |
42 | - router.addRoute(RootRoute.name!, route as RouteRecordRaw); | 43 | + router.addRoute(route as RouteRecordRaw); |
43 | }); | 44 | }); |
44 | permissionStore.commitLastBuildMenuTimeState(); | 45 | permissionStore.commitLastBuildMenuTimeState(); |
45 | - const { | ||
46 | - // closeAll, | ||
47 | - closeOther, | ||
48 | - } = useTabs(); | ||
49 | - // closeAll(); | ||
50 | - closeOther(); | 46 | + const { closeAll } = useTabs(); |
47 | + closeAll(); | ||
51 | } | 48 | } |
52 | 49 | ||
53 | /** | 50 | /** |
src/hooks/web/useTabs.ts
1 | -import { TabItem, tabStore } from '/@/store/modules/tab'; | 1 | +import { tabStore } from '/@/store/modules/tab'; |
2 | import { appStore } from '/@/store/modules/app'; | 2 | import { appStore } from '/@/store/modules/app'; |
3 | 3 | ||
4 | -type RouteFn = (tabItem: TabItem) => void; | ||
5 | - | ||
6 | -interface TabFn { | ||
7 | - refreshPageFn: RouteFn; | ||
8 | - closeAllFn: Fn; | ||
9 | - closeLeftFn: RouteFn; | ||
10 | - closeRightFn: RouteFn; | ||
11 | - closeOtherFn: RouteFn; | ||
12 | - closeCurrentFn: RouteFn; | ||
13 | -} | ||
14 | - | ||
15 | -let refreshPage: RouteFn; | ||
16 | -let closeAll: Fn; | ||
17 | -let closeLeft: RouteFn; | ||
18 | -let closeRight: RouteFn; | ||
19 | -let closeOther: RouteFn; | ||
20 | -let closeCurrent: RouteFn; | ||
21 | - | ||
22 | -export let isInitUseTab = false; | ||
23 | - | ||
24 | export function useTabs() { | 4 | export function useTabs() { |
25 | - function initTabFn({ | ||
26 | - refreshPageFn, | ||
27 | - closeAllFn, | ||
28 | - closeLeftFn, | ||
29 | - closeRightFn, | ||
30 | - closeOtherFn, | ||
31 | - closeCurrentFn, | ||
32 | - }: TabFn) { | ||
33 | - if (isInitUseTab) return; | ||
34 | - | ||
35 | - refreshPageFn && (refreshPage = refreshPageFn); | ||
36 | - closeAllFn && (closeAll = closeAllFn); | ||
37 | - closeLeftFn && (closeLeft = closeLeftFn); | ||
38 | - closeRightFn && (closeRight = closeRightFn); | ||
39 | - closeOtherFn && (closeOther = closeOtherFn); | ||
40 | - closeCurrentFn && (closeCurrent = closeCurrentFn); | ||
41 | - isInitUseTab = true; | ||
42 | - } | ||
43 | - | ||
44 | - function resetCache() { | ||
45 | - const def = undefined as any; | ||
46 | - refreshPage = def; | ||
47 | - closeAll = def; | ||
48 | - closeLeft = def; | ||
49 | - closeRight = def; | ||
50 | - closeOther = def; | ||
51 | - closeCurrent = def; | ||
52 | - } | ||
53 | - | ||
54 | function canIUseFn(): boolean { | 5 | function canIUseFn(): boolean { |
55 | const { multiTabsSetting: { show } = {} } = appStore.getProjectConfig; | 6 | const { multiTabsSetting: { show } = {} } = appStore.getProjectConfig; |
56 | if (!show) { | 7 | if (!show) { |
57 | - throw new Error('当前未开启多标签页,请在设置中打开!'); | 8 | + throw new Error('The multi-tab page is currently not open, please open it in the settings!'); |
58 | } | 9 | } |
59 | return !!show; | 10 | return !!show; |
60 | } | 11 | } |
61 | 12 | ||
62 | return { | 13 | return { |
63 | - initTabFn, | ||
64 | - refreshPage: () => canIUseFn() && refreshPage(tabStore.getCurrentTab), | ||
65 | - closeAll: () => canIUseFn() && closeAll(), | ||
66 | - closeLeft: () => canIUseFn() && closeLeft(tabStore.getCurrentTab), | ||
67 | - closeRight: () => canIUseFn() && closeRight(tabStore.getCurrentTab), | ||
68 | - closeOther: () => canIUseFn() && closeOther(tabStore.getCurrentTab), | ||
69 | - closeCurrent: () => canIUseFn() && closeCurrent(tabStore.getCurrentTab), | ||
70 | - resetCache: () => canIUseFn() && resetCache(), | 14 | + refreshPage: () => canIUseFn() && tabStore.commitRedoPage(), |
15 | + closeAll: () => canIUseFn() && tabStore.closeAllTabAction(), | ||
16 | + closeLeft: () => canIUseFn() && tabStore.closeLeftTabAction(tabStore.getCurrentTab), | ||
17 | + closeRight: () => canIUseFn() && tabStore.closeRightTabAction(tabStore.getCurrentTab), | ||
18 | + closeOther: () => canIUseFn() && tabStore.closeOtherTabAction(tabStore.getCurrentTab), | ||
19 | + closeCurrent: () => canIUseFn() && tabStore.closeTabAction(tabStore.getCurrentTab), | ||
71 | }; | 20 | }; |
72 | } | 21 | } |
src/layouts/default/content/index.tsx
@@ -3,11 +3,9 @@ import './index.less'; | @@ -3,11 +3,9 @@ import './index.less'; | ||
3 | import { defineComponent, unref } from 'vue'; | 3 | import { defineComponent, unref } from 'vue'; |
4 | import { Loading } from '/@/components/Loading'; | 4 | import { Loading } from '/@/components/Loading'; |
5 | 5 | ||
6 | -import { RouterView } from 'vue-router'; | ||
7 | - | ||
8 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | 6 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
9 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; | 7 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; |
10 | - | 8 | +import PageLayout from '/@/layouts/page/index.vue'; |
11 | export default defineComponent({ | 9 | export default defineComponent({ |
12 | name: 'LayoutContent', | 10 | name: 'LayoutContent', |
13 | setup() { | 11 | setup() { |
@@ -20,7 +18,7 @@ export default defineComponent({ | @@ -20,7 +18,7 @@ export default defineComponent({ | ||
20 | {unref(getOpenPageLoading) && ( | 18 | {unref(getOpenPageLoading) && ( |
21 | <Loading loading={unref(getPageLoading)} absolute class="layout-content__loading" /> | 19 | <Loading loading={unref(getPageLoading)} absolute class="layout-content__loading" /> |
22 | )} | 20 | )} |
23 | - <RouterView /> | 21 | + <PageLayout /> |
24 | </div> | 22 | </div> |
25 | ); | 23 | ); |
26 | }; | 24 | }; |
src/layouts/default/header/LayoutBreadcrumb.tsx deleted
100644 → 0
1 | -import type { AppRouteRecordRaw } from '/@/router/types'; | ||
2 | -import type { RouteLocationMatched } from 'vue-router'; | ||
3 | -import type { PropType } from 'vue'; | ||
4 | - | ||
5 | -import { defineComponent, TransitionGroup, unref, watch, ref } from 'vue'; | ||
6 | -import Icon from '/@/components/Icon'; | ||
7 | - | ||
8 | -import { Breadcrumb, BreadcrumbItem } from '/@/components/Breadcrumb'; | ||
9 | - | ||
10 | -import { useRouter } from 'vue-router'; | ||
11 | - | ||
12 | -import { isBoolean } from '/@/utils/is'; | ||
13 | -import { compile } from 'path-to-regexp'; | ||
14 | - | ||
15 | -import router from '/@/router'; | ||
16 | - | ||
17 | -import { PageEnum } from '/@/enums/pageEnum'; | ||
18 | -import { useI18n } from '/@/hooks/web/useI18n'; | ||
19 | - | ||
20 | -export default defineComponent({ | ||
21 | - name: 'BasicBreadcrumb', | ||
22 | - props: { | ||
23 | - showIcon: { | ||
24 | - type: Boolean as PropType<boolean>, | ||
25 | - default: false, | ||
26 | - }, | ||
27 | - }, | ||
28 | - setup(props) { | ||
29 | - const itemList = ref<AppRouteRecordRaw[]>([]); | ||
30 | - | ||
31 | - const { currentRoute, push } = useRouter(); | ||
32 | - const { t } = useI18n(); | ||
33 | - watch( | ||
34 | - () => currentRoute.value, | ||
35 | - () => { | ||
36 | - if (unref(currentRoute).name === 'Redirect') return; | ||
37 | - getBreadcrumb(); | ||
38 | - }, | ||
39 | - { immediate: true } | ||
40 | - ); | ||
41 | - | ||
42 | - function getBreadcrumb() { | ||
43 | - const { matched } = unref(currentRoute); | ||
44 | - const matchedList = matched.filter((item) => item.meta && item.meta.title).slice(1); | ||
45 | - const firstItem = matchedList[0]; | ||
46 | - const ret = getHomeRoute(firstItem); | ||
47 | - if (!isBoolean(ret)) { | ||
48 | - matchedList.unshift(ret); | ||
49 | - } | ||
50 | - itemList.value = ((matchedList as any) as AppRouteRecordRaw[]).filter( | ||
51 | - (item) => item.meta && item.meta.title && !item.meta.hideBreadcrumb | ||
52 | - ); | ||
53 | - } | ||
54 | - | ||
55 | - function getHomeRoute(firstItem: RouteLocationMatched) { | ||
56 | - if (!firstItem || !firstItem.name) return false; | ||
57 | - const routes = router.getRoutes(); | ||
58 | - const homeRoute = routes.find((item) => item.path === PageEnum.BASE_HOME); | ||
59 | - if (!homeRoute) return false; | ||
60 | - if (homeRoute.name === firstItem.name) return false; | ||
61 | - return homeRoute; | ||
62 | - } | ||
63 | - | ||
64 | - function pathCompile(path: string) { | ||
65 | - const { params } = unref(currentRoute); | ||
66 | - const toPath = compile(path); | ||
67 | - return toPath(params); | ||
68 | - } | ||
69 | - | ||
70 | - function handleItemClick(item: AppRouteRecordRaw) { | ||
71 | - const { redirect, path, meta } = item; | ||
72 | - if (meta.disabledRedirect) return; | ||
73 | - if (redirect) { | ||
74 | - push(redirect as string); | ||
75 | - return; | ||
76 | - } | ||
77 | - return push(pathCompile(path)); | ||
78 | - } | ||
79 | - | ||
80 | - function renderItemContent(item: AppRouteRecordRaw) { | ||
81 | - return ( | ||
82 | - <> | ||
83 | - {props.showIcon && item.meta.icon && item.meta.icon.trim() !== '' && ( | ||
84 | - <Icon | ||
85 | - icon={item.meta.icon} | ||
86 | - class="icon mr-1 " | ||
87 | - style={{ | ||
88 | - marginBottom: '2px', | ||
89 | - }} | ||
90 | - /> | ||
91 | - )} | ||
92 | - {t(item.meta.title)} | ||
93 | - </> | ||
94 | - ); | ||
95 | - } | ||
96 | - | ||
97 | - function renderBreadcrumbItemList() { | ||
98 | - return unref(itemList).map((item) => { | ||
99 | - const isLink = | ||
100 | - (!!item.redirect && !item.meta.disabledRedirect) || | ||
101 | - !item.children || | ||
102 | - item.children.length === 0; | ||
103 | - | ||
104 | - return ( | ||
105 | - <BreadcrumbItem | ||
106 | - key={item.path} | ||
107 | - isLink={isLink} | ||
108 | - onClick={handleItemClick.bind(null, item)} | ||
109 | - > | ||
110 | - {() => renderItemContent(item as AppRouteRecordRaw)} | ||
111 | - </BreadcrumbItem> | ||
112 | - ); | ||
113 | - }); | ||
114 | - } | ||
115 | - | ||
116 | - function renderBreadcrumbDefault() { | ||
117 | - return ( | ||
118 | - <TransitionGroup name="breadcrumb">{() => renderBreadcrumbItemList()}</TransitionGroup> | ||
119 | - ); | ||
120 | - } | ||
121 | - | ||
122 | - return () => ( | ||
123 | - <Breadcrumb class={['layout-breadcrumb', unref(itemList).length === 0 ? 'hidden' : '']}> | ||
124 | - {() => renderBreadcrumbDefault()} | ||
125 | - </Breadcrumb> | ||
126 | - ); | ||
127 | - }, | ||
128 | -}); |
src/layouts/default/header/LayoutBreadcrumb.vue
0 → 100644
1 | +<template> | ||
2 | + <div class="layout-breadcrumb"> | ||
3 | + <a-breadcrumb :routes="routes"> | ||
4 | + <template #itemRender="{ route, routes }"> | ||
5 | + <Icon :icon="route.meta.icon" v-if="showIcon && route.meta.icon" /> | ||
6 | + <span v-if="routes.indexOf(route) === routes.length - 1"> | ||
7 | + {{ t(route.meta.title) }} | ||
8 | + </span> | ||
9 | + <router-link v-else :to="route.path"> | ||
10 | + {{ t(route.meta.title) }} | ||
11 | + </router-link> | ||
12 | + </template> | ||
13 | + </a-breadcrumb> | ||
14 | + </div> | ||
15 | +</template> | ||
16 | +<script lang="ts"> | ||
17 | + import { PropType } from 'vue'; | ||
18 | + import { defineComponent, ref, toRaw, watchEffect } from 'vue'; | ||
19 | + import { useI18n } from 'vue-i18n'; | ||
20 | + | ||
21 | + import type { RouteLocationMatched } from 'vue-router'; | ||
22 | + import { useRouter } from 'vue-router'; | ||
23 | + import { filter } from '/@/utils/helper/treeHelper'; | ||
24 | + import { REDIRECT_NAME } from '/@/router/constant'; | ||
25 | + import Icon from '/@/components/Icon'; | ||
26 | + | ||
27 | + import { HomeOutlined } from '@ant-design/icons-vue'; | ||
28 | + import { PageEnum } from '/@/enums/pageEnum'; | ||
29 | + export default defineComponent({ | ||
30 | + name: 'LayoutBreadcrumb', | ||
31 | + components: { HomeOutlined, Icon }, | ||
32 | + props: { | ||
33 | + showIcon: { | ||
34 | + type: Boolean as PropType<boolean>, | ||
35 | + default: false, | ||
36 | + }, | ||
37 | + }, | ||
38 | + setup() { | ||
39 | + const routes = ref<RouteLocationMatched[]>([]); | ||
40 | + const { currentRoute } = useRouter(); | ||
41 | + | ||
42 | + const { t } = useI18n(); | ||
43 | + watchEffect(() => { | ||
44 | + if (currentRoute.value.name === REDIRECT_NAME) { | ||
45 | + return; | ||
46 | + } | ||
47 | + const matched = currentRoute.value.matched; | ||
48 | + if (!matched || matched.length === 0) return; | ||
49 | + | ||
50 | + let breadcrumbList = filter(toRaw(matched), (item) => { | ||
51 | + if (!item.meta) { | ||
52 | + return false; | ||
53 | + } | ||
54 | + const { title, hideBreadcrumb } = item.meta; | ||
55 | + if (!title || hideBreadcrumb) { | ||
56 | + return false; | ||
57 | + } | ||
58 | + return true; | ||
59 | + }); | ||
60 | + | ||
61 | + const filterBreadcrumbList = breadcrumbList.filter( | ||
62 | + (item) => item.path !== PageEnum.BASE_HOME | ||
63 | + ); | ||
64 | + | ||
65 | + if (filterBreadcrumbList.length === breadcrumbList.length) { | ||
66 | + filterBreadcrumbList.unshift({ | ||
67 | + path: PageEnum.BASE_HOME, | ||
68 | + meta: { | ||
69 | + title: t('layout.header.home'), | ||
70 | + }, | ||
71 | + }); | ||
72 | + } | ||
73 | + routes.value = filterBreadcrumbList; | ||
74 | + }); | ||
75 | + | ||
76 | + return { routes, t }; | ||
77 | + }, | ||
78 | + }); | ||
79 | +</script> |
src/layouts/default/header/LayoutHeader.tsx
@@ -9,7 +9,7 @@ import { Layout, Tooltip, Badge } from 'ant-design-vue'; | @@ -9,7 +9,7 @@ import { Layout, Tooltip, Badge } from 'ant-design-vue'; | ||
9 | import { AppLogo } from '/@/components/Application'; | 9 | import { AppLogo } from '/@/components/Application'; |
10 | import UserDropdown from './UserDropdown'; | 10 | import UserDropdown from './UserDropdown'; |
11 | import LayoutMenu from '../menu'; | 11 | import LayoutMenu from '../menu'; |
12 | -import LayoutBreadcrumb from './LayoutBreadcrumb'; | 12 | +import LayoutBreadcrumb from './LayoutBreadcrumb.vue'; |
13 | import LockAction from '../lock/LockAction'; | 13 | import LockAction from '../lock/LockAction'; |
14 | import LayoutTrigger from '../LayoutTrigger'; | 14 | import LayoutTrigger from '../LayoutTrigger'; |
15 | import NoticeAction from './notice/NoticeActionItem.vue'; | 15 | import NoticeAction from './notice/NoticeActionItem.vue'; |
src/layouts/default/header/LayoutMultipleHeader.less
src/layouts/default/header/index.less
@@ -21,11 +21,15 @@ | @@ -21,11 +21,15 @@ | ||
21 | 21 | ||
22 | &__left { | 22 | &__left { |
23 | display: flex; | 23 | display: flex; |
24 | + height: 100%; | ||
24 | align-items: center; | 25 | align-items: center; |
25 | 26 | ||
26 | .layout-trigger { | 27 | .layout-trigger { |
28 | + display: flex; | ||
29 | + height: 100%; | ||
27 | padding: 1px 10px 0 16px; | 30 | padding: 1px 10px 0 16px; |
28 | cursor: pointer; | 31 | cursor: pointer; |
32 | + align-items: center; | ||
29 | 33 | ||
30 | .anticon { | 34 | .anticon { |
31 | font-size: 17px; | 35 | font-size: 17px; |
@@ -49,12 +53,22 @@ | @@ -49,12 +53,22 @@ | ||
49 | } | 53 | } |
50 | 54 | ||
51 | .layout-breadcrumb { | 55 | .layout-breadcrumb { |
56 | + display: flex; | ||
52 | padding: 0 8px; | 57 | padding: 0 8px; |
58 | + align-items: center; | ||
59 | + | ||
60 | + .ant-breadcrumb-link { | ||
61 | + .anticon { | ||
62 | + margin-right: 4px; | ||
63 | + margin-bottom: 2px; | ||
64 | + } | ||
65 | + } | ||
53 | } | 66 | } |
54 | } | 67 | } |
55 | 68 | ||
56 | &__content { | 69 | &__content { |
57 | display: flex; | 70 | display: flex; |
71 | + height: 100%; | ||
58 | flex-grow: 1; | 72 | flex-grow: 1; |
59 | align-items: center; | 73 | align-items: center; |
60 | } | 74 | } |
@@ -72,6 +86,24 @@ | @@ -72,6 +86,24 @@ | ||
72 | } | 86 | } |
73 | } | 87 | } |
74 | 88 | ||
89 | + .layout-breadcrumb { | ||
90 | + .ant-breadcrumb-link { | ||
91 | + color: @breadcrumb-item-normal-color; | ||
92 | + | ||
93 | + a { | ||
94 | + color: @text-color-base; | ||
95 | + | ||
96 | + &:hover { | ||
97 | + color: @primary-color; | ||
98 | + } | ||
99 | + } | ||
100 | + } | ||
101 | + | ||
102 | + .ant-breadcrumb-separator { | ||
103 | + color: @breadcrumb-item-normal-color; | ||
104 | + } | ||
105 | + } | ||
106 | + | ||
75 | .layout-header__logo { | 107 | .layout-header__logo { |
76 | height: @header-height; | 108 | height: @header-height; |
77 | color: @text-color-base; | 109 | color: @text-color-base; |
@@ -152,20 +184,22 @@ | @@ -152,20 +184,22 @@ | ||
152 | } | 184 | } |
153 | } | 185 | } |
154 | 186 | ||
155 | - .breadcrumb { | ||
156 | - &__item:last-child .breadcrumb__inner, | ||
157 | - &__item:last-child &__inner a, | ||
158 | - &__item:last-child &__inner a:hover, | ||
159 | - &__item:last-child &__inner:hover { | ||
160 | - font-weight: 400; | 187 | + .layout-breadcrumb { |
188 | + .ant-breadcrumb-link { | ||
161 | color: rgba(255, 255, 255, 0.6); | 189 | color: rgba(255, 255, 255, 0.6); |
162 | - cursor: text; | 190 | + |
191 | + a { | ||
192 | + color: rgba(255, 255, 255, 0.8); | ||
193 | + | ||
194 | + &:hover { | ||
195 | + color: @white; | ||
196 | + } | ||
197 | + } | ||
163 | } | 198 | } |
164 | 199 | ||
165 | - &__inner, | ||
166 | - &__inner.is-link, | ||
167 | - &__separator { | ||
168 | - color: @white; | 200 | + .ant-breadcrumb-separator, |
201 | + .anticon { | ||
202 | + color: rgba(255, 255, 255, 0.8); | ||
169 | } | 203 | } |
170 | } | 204 | } |
171 | } | 205 | } |
src/layouts/default/multitabs/TabContent.tsx
1 | import type { PropType } from 'vue'; | 1 | import type { PropType } from 'vue'; |
2 | +import { Dropdown } from '/@/components/Dropdown/index'; | ||
2 | 3 | ||
3 | -import { defineComponent, unref, computed, FunctionalComponent } from 'vue'; | 4 | +import { defineComponent, unref, FunctionalComponent } from 'vue'; |
4 | 5 | ||
5 | -import { TabItem, tabStore } from '/@/store/modules/tab'; | ||
6 | -import { getScaleAction, TabContentProps } from './data'; | 6 | +import { TabContentProps } from './types'; |
7 | 7 | ||
8 | -import { Dropdown } from '/@/components/Dropdown/index'; | ||
9 | import { RightOutlined } from '@ant-design/icons-vue'; | 8 | import { RightOutlined } from '@ant-design/icons-vue'; |
10 | 9 | ||
11 | -import { TabContentEnum } from './data'; | 10 | +import { TabContentEnum } from './types'; |
11 | + | ||
12 | import { useTabDropdown } from './useTabDropdown'; | 12 | import { useTabDropdown } from './useTabDropdown'; |
13 | -import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | ||
14 | -import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; | ||
15 | -import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; | ||
16 | import { useI18n } from '/@/hooks/web/useI18n'; | 13 | import { useI18n } from '/@/hooks/web/useI18n'; |
17 | 14 | ||
15 | +import { RouteLocationNormalized } from 'vue-router'; | ||
16 | + | ||
18 | const { t: titleT } = useI18n(); | 17 | const { t: titleT } = useI18n(); |
19 | 18 | ||
20 | const ExtraContent: FunctionalComponent = () => { | 19 | const ExtraContent: FunctionalComponent = () => { |
@@ -25,21 +24,13 @@ const ExtraContent: FunctionalComponent = () => { | @@ -25,21 +24,13 @@ const ExtraContent: FunctionalComponent = () => { | ||
25 | ); | 24 | ); |
26 | }; | 25 | }; |
27 | 26 | ||
28 | -const TabContent: FunctionalComponent<{ tabItem: TabItem }> = (props) => { | 27 | +const TabContent: FunctionalComponent<{ tabItem: RouteLocationNormalized; handler: Fn }> = ( |
28 | + props | ||
29 | +) => { | ||
29 | const { tabItem: { meta } = {} } = props; | 30 | const { tabItem: { meta } = {} } = props; |
30 | 31 | ||
31 | - function handleContextMenu(e: Event) { | ||
32 | - if (!props.tabItem) return; | ||
33 | - const tableItem = props.tabItem; | ||
34 | - e?.preventDefault(); | ||
35 | - const index = unref(tabStore.getTabsState).findIndex((tab) => tab.path === tableItem.path); | ||
36 | - | ||
37 | - tabStore.commitCurrentContextMenuIndexState(index); | ||
38 | - tabStore.commitCurrentContextMenuState(props.tabItem); | ||
39 | - } | ||
40 | - | ||
41 | return ( | 32 | return ( |
42 | - <div class={`multiple-tabs-content__content `} onContextmenu={handleContextMenu}> | 33 | + <div class={`multiple-tabs-content__content `} onContextmenu={props.handler(props.tabItem)}> |
43 | <span class="ml-1">{meta && titleT(meta.title)}</span> | 34 | <span class="ml-1">{meta && titleT(meta.title)}</span> |
44 | </div> | 35 | </div> |
45 | ); | 36 | ); |
@@ -49,7 +40,7 @@ export default defineComponent({ | @@ -49,7 +40,7 @@ export default defineComponent({ | ||
49 | name: 'TabContent', | 40 | name: 'TabContent', |
50 | props: { | 41 | props: { |
51 | tabItem: { | 42 | tabItem: { |
52 | - type: Object as PropType<TabItem>, | 43 | + type: Object as PropType<RouteLocationNormalized>, |
53 | default: null, | 44 | default: null, |
54 | }, | 45 | }, |
55 | 46 | ||
@@ -59,36 +50,27 @@ export default defineComponent({ | @@ -59,36 +50,27 @@ export default defineComponent({ | ||
59 | }, | 50 | }, |
60 | }, | 51 | }, |
61 | setup(props) { | 52 | setup(props) { |
62 | - const { t } = useI18n(); | ||
63 | - const { getShowMenu } = useMenuSetting(); | ||
64 | - const { getShowHeader } = useHeaderSetting(); | ||
65 | - const { getShowQuick } = useMultipleTabSetting(); | ||
66 | - | ||
67 | - const getIsScale = computed(() => { | ||
68 | - return !unref(getShowMenu) && !unref(getShowHeader); | ||
69 | - }); | ||
70 | - | ||
71 | - const getIsTab = computed(() => { | ||
72 | - return !unref(getShowQuick) ? true : props.type === TabContentEnum.TAB_TYPE; | ||
73 | - }); | ||
74 | - | ||
75 | - const { getDropMenuList, handleMenuEvent } = useTabDropdown(props as TabContentProps); | 53 | + const { |
54 | + getDropMenuList, | ||
55 | + handleMenuEvent, | ||
56 | + handleContextMenu, | ||
57 | + getTrigger, | ||
58 | + isTabs, | ||
59 | + } = useTabDropdown(props as TabContentProps); | ||
76 | 60 | ||
77 | return () => { | 61 | return () => { |
78 | - const scaleAction = getScaleAction( | ||
79 | - unref(getIsScale) ? t('layout.multipleTab.putAway') : t('layout.multipleTab.unfold'), | ||
80 | - unref(getIsScale) | ||
81 | - ); | ||
82 | - const dropMenuList = unref(getDropMenuList) || []; | ||
83 | - | ||
84 | - const isTab = unref(getIsTab); | ||
85 | return ( | 62 | return ( |
86 | <Dropdown | 63 | <Dropdown |
87 | - dropMenuList={!isTab ? [scaleAction, ...dropMenuList] : dropMenuList} | ||
88 | - trigger={isTab ? ['contextmenu'] : ['click']} | 64 | + dropMenuList={unref(getDropMenuList)} |
65 | + trigger={unref(getTrigger)} | ||
89 | onMenuEvent={handleMenuEvent} | 66 | onMenuEvent={handleMenuEvent} |
90 | > | 67 | > |
91 | - {() => (isTab ? <TabContent tabItem={props.tabItem} /> : <ExtraContent />)} | 68 | + {() => { |
69 | + if (!unref(isTabs)) { | ||
70 | + return <ExtraContent />; | ||
71 | + } | ||
72 | + return <TabContent handler={handleContextMenu} tabItem={props.tabItem} />; | ||
73 | + }} | ||
92 | </Dropdown> | 74 | </Dropdown> |
93 | ); | 75 | ); |
94 | }; | 76 | }; |
src/layouts/default/multitabs/data.ts deleted
100644 → 0
1 | -import { DropMenu } from '/@/components/Dropdown/index'; | ||
2 | -import { AppRouteRecordRaw } from '/@/router/types'; | ||
3 | -import type { TabItem } from '/@/store/modules/tab'; | ||
4 | - | ||
5 | -import { useI18n } from '/@/hooks/web/useI18n'; | ||
6 | - | ||
7 | -const { t } = useI18n(); | ||
8 | - | ||
9 | -export enum TabContentEnum { | ||
10 | - TAB_TYPE, | ||
11 | - EXTRA_TYPE, | ||
12 | -} | ||
13 | - | ||
14 | -export interface TabContentProps { | ||
15 | - tabItem: TabItem | AppRouteRecordRaw; | ||
16 | - type?: TabContentEnum; | ||
17 | - trigger?: Array<'click' | 'hover' | 'contextmenu'>; | ||
18 | -} | ||
19 | - | ||
20 | -/** | ||
21 | - * @description: 右键:下拉菜单文字 | ||
22 | - */ | ||
23 | -export enum MenuEventEnum { | ||
24 | - // 刷新 | ||
25 | - REFRESH_PAGE, | ||
26 | - // 关闭当前 | ||
27 | - CLOSE_CURRENT, | ||
28 | - // 关闭左侧 | ||
29 | - CLOSE_LEFT, | ||
30 | - // 关闭右侧 | ||
31 | - CLOSE_RIGHT, | ||
32 | - // 关闭其他 | ||
33 | - CLOSE_OTHER, | ||
34 | - // 关闭所有 | ||
35 | - CLOSE_ALL, | ||
36 | - // 放大 | ||
37 | - SCALE, | ||
38 | -} | ||
39 | - | ||
40 | -export function getActions() { | ||
41 | - const REFRESH_PAGE: DropMenu = { | ||
42 | - icon: 'ant-design:reload-outlined', | ||
43 | - event: MenuEventEnum.REFRESH_PAGE, | ||
44 | - text: t('layout.multipleTab.redo'), | ||
45 | - disabled: false, | ||
46 | - }; | ||
47 | - const CLOSE_CURRENT: DropMenu = { | ||
48 | - icon: 'ant-design:close-outlined', | ||
49 | - event: MenuEventEnum.CLOSE_CURRENT, | ||
50 | - text: t('layout.multipleTab.close'), | ||
51 | - disabled: false, | ||
52 | - divider: true, | ||
53 | - }; | ||
54 | - const CLOSE_LEFT: DropMenu = { | ||
55 | - icon: 'ant-design:pic-left-outlined', | ||
56 | - event: MenuEventEnum.CLOSE_LEFT, | ||
57 | - text: t('layout.multipleTab.closeLeft'), | ||
58 | - disabled: false, | ||
59 | - divider: false, | ||
60 | - }; | ||
61 | - const CLOSE_RIGHT: DropMenu = { | ||
62 | - icon: 'ant-design:pic-right-outlined', | ||
63 | - event: MenuEventEnum.CLOSE_RIGHT, | ||
64 | - text: t('layout.multipleTab.closeRight'), | ||
65 | - disabled: false, | ||
66 | - divider: true, | ||
67 | - }; | ||
68 | - const CLOSE_OTHER: DropMenu = { | ||
69 | - icon: 'ant-design:pic-center-outlined', | ||
70 | - event: MenuEventEnum.CLOSE_OTHER, | ||
71 | - text: t('layout.multipleTab.closeOther'), | ||
72 | - disabled: false, | ||
73 | - }; | ||
74 | - const CLOSE_ALL: DropMenu = { | ||
75 | - icon: 'ant-design:line-outlined', | ||
76 | - event: MenuEventEnum.CLOSE_ALL, | ||
77 | - text: t('layout.multipleTab.closeAll'), | ||
78 | - disabled: false, | ||
79 | - }; | ||
80 | - return [REFRESH_PAGE, CLOSE_CURRENT, CLOSE_LEFT, CLOSE_RIGHT, CLOSE_OTHER, CLOSE_ALL]; | ||
81 | -} | ||
82 | - | ||
83 | -export function getScaleAction(text: string, isZoom = false) { | ||
84 | - return { | ||
85 | - icon: isZoom ? 'codicon:screen-normal' : 'codicon:screen-full', | ||
86 | - event: MenuEventEnum.SCALE, | ||
87 | - text: text, | ||
88 | - disabled: false, | ||
89 | - }; | ||
90 | -} |
src/layouts/default/multitabs/index.tsx
1 | import './index.less'; | 1 | import './index.less'; |
2 | 2 | ||
3 | -import type { TabContentProps } from './data'; | ||
4 | -import type { TabItem } from '/@/store/modules/tab'; | ||
5 | -import type { AppRouteRecordRaw } from '/@/router/types'; | ||
6 | - | ||
7 | -import { defineComponent, watch, computed, unref, ref, onMounted, nextTick } from 'vue'; | ||
8 | -import Sortable from 'sortablejs'; | 3 | +import type { TabContentProps } from './types'; |
9 | 4 | ||
5 | +import { defineComponent, watch, computed, unref, ref } from 'vue'; | ||
10 | import { useRouter } from 'vue-router'; | 6 | import { useRouter } from 'vue-router'; |
11 | 7 | ||
12 | import { Tabs } from 'ant-design-vue'; | 8 | import { Tabs } from 'ant-design-vue'; |
@@ -14,15 +10,12 @@ import TabContent from './TabContent'; | @@ -14,15 +10,12 @@ import TabContent from './TabContent'; | ||
14 | 10 | ||
15 | import { useGo } from '/@/hooks/web/usePage'; | 11 | import { useGo } from '/@/hooks/web/usePage'; |
16 | 12 | ||
17 | -import { TabContentEnum } from './data'; | 13 | +import { TabContentEnum } from './types'; |
18 | 14 | ||
19 | import { tabStore } from '/@/store/modules/tab'; | 15 | import { tabStore } from '/@/store/modules/tab'; |
20 | import { userStore } from '/@/store/modules/user'; | 16 | import { userStore } from '/@/store/modules/user'; |
21 | 17 | ||
22 | -import { closeTab } from './useTabDropdown'; | ||
23 | -import { initAffixTabs } from './useMultipleTabs'; | ||
24 | -import { isNullAndUnDef } from '/@/utils/is'; | ||
25 | -import { useProjectSetting } from '/@/hooks/setting'; | 18 | +import { initAffixTabs, useTabsDrag } from './useMultipleTabs'; |
26 | 19 | ||
27 | export default defineComponent({ | 20 | export default defineComponent({ |
28 | name: 'MultipleTabs', | 21 | name: 'MultipleTabs', |
@@ -31,28 +24,25 @@ export default defineComponent({ | @@ -31,28 +24,25 @@ export default defineComponent({ | ||
31 | 24 | ||
32 | const affixTextList = initAffixTabs(); | 25 | const affixTextList = initAffixTabs(); |
33 | 26 | ||
34 | - const go = useGo(); | 27 | + useTabsDrag(affixTextList); |
35 | 28 | ||
36 | - const { multiTabsSetting } = useProjectSetting(); | 29 | + const go = useGo(); |
37 | 30 | ||
38 | const { currentRoute } = useRouter(); | 31 | const { currentRoute } = useRouter(); |
39 | 32 | ||
40 | const getTabsState = computed(() => tabStore.getTabsState); | 33 | const getTabsState = computed(() => tabStore.getTabsState); |
41 | 34 | ||
42 | - // If you monitor routing changes, tab switching will be stuck. So setting this method | ||
43 | watch( | 35 | watch( |
44 | - () => tabStore.getLastChangeRouteState, | 36 | + () => tabStore.getLastChangeRouteState?.path, |
45 | () => { | 37 | () => { |
46 | const lastChangeRoute = unref(tabStore.getLastChangeRouteState); | 38 | const lastChangeRoute = unref(tabStore.getLastChangeRouteState); |
47 | - | ||
48 | if (!lastChangeRoute || !userStore.getTokenState) return; | 39 | if (!lastChangeRoute || !userStore.getTokenState) return; |
49 | - | ||
50 | - const { path, fullPath } = lastChangeRoute as AppRouteRecordRaw; | 40 | + const { path, fullPath } = lastChangeRoute; |
51 | const p = fullPath || path; | 41 | const p = fullPath || path; |
52 | if (activeKeyRef.value !== p) { | 42 | if (activeKeyRef.value !== p) { |
53 | activeKeyRef.value = p; | 43 | activeKeyRef.value = p; |
54 | } | 44 | } |
55 | - tabStore.commitAddTab(lastChangeRoute); | 45 | + tabStore.addTabAction(lastChangeRoute); |
56 | }, | 46 | }, |
57 | { | 47 | { |
58 | immediate: true, | 48 | immediate: true, |
@@ -67,22 +57,19 @@ export default defineComponent({ | @@ -67,22 +57,19 @@ export default defineComponent({ | ||
67 | // Close the current tab | 57 | // Close the current tab |
68 | function handleEdit(targetKey: string) { | 58 | function handleEdit(targetKey: string) { |
69 | // Added operation to hide, currently only use delete operation | 59 | // Added operation to hide, currently only use delete operation |
70 | - const index = unref(getTabsState).findIndex( | ||
71 | - (item) => (item.fullPath || item.path) === targetKey | ||
72 | - ); | ||
73 | - index !== -1 && closeTab(unref(getTabsState)[index]); | 60 | + tabStore.closeTabByKeyAction(targetKey); |
74 | } | 61 | } |
75 | 62 | ||
76 | function renderQuick() { | 63 | function renderQuick() { |
77 | const tabContentProps: TabContentProps = { | 64 | const tabContentProps: TabContentProps = { |
78 | - tabItem: (currentRoute as unknown) as AppRouteRecordRaw, | 65 | + tabItem: currentRoute.value, |
79 | type: TabContentEnum.EXTRA_TYPE, | 66 | type: TabContentEnum.EXTRA_TYPE, |
80 | }; | 67 | }; |
81 | - return <TabContent {...(tabContentProps as any)} />; | 68 | + return <TabContent {...tabContentProps} />; |
82 | } | 69 | } |
83 | 70 | ||
84 | function renderTabs() { | 71 | function renderTabs() { |
85 | - return unref(getTabsState).map((item: TabItem) => { | 72 | + return unref(getTabsState).map((item) => { |
86 | const key = item.query ? item.fullPath : item.path; | 73 | const key = item.query ? item.fullPath : item.path; |
87 | const closable = !(item && item.meta && item.meta.affix); | 74 | const closable = !(item && item.meta && item.meta.affix); |
88 | 75 | ||
@@ -97,40 +84,6 @@ export default defineComponent({ | @@ -97,40 +84,6 @@ export default defineComponent({ | ||
97 | }); | 84 | }); |
98 | } | 85 | } |
99 | 86 | ||
100 | - function initSortableTabs() { | ||
101 | - if (!multiTabsSetting.canDrag) return; | ||
102 | - nextTick(() => { | ||
103 | - const el = document.querySelectorAll( | ||
104 | - '.multiple-tabs .ant-tabs-nav > div' | ||
105 | - )?.[0] as HTMLElement; | ||
106 | - | ||
107 | - if (!el) return; | ||
108 | - Sortable.create(el, { | ||
109 | - animation: 500, | ||
110 | - delay: 400, | ||
111 | - delayOnTouchOnly: true, | ||
112 | - filter: (e: ChangeEvent) => { | ||
113 | - const text = e?.target?.innerText; | ||
114 | - if (!text) return false; | ||
115 | - return affixTextList.includes(text); | ||
116 | - }, | ||
117 | - onEnd: (evt) => { | ||
118 | - const { oldIndex, newIndex } = evt; | ||
119 | - | ||
120 | - if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) { | ||
121 | - return; | ||
122 | - } | ||
123 | - | ||
124 | - tabStore.commitSortTabs({ oldIndex, newIndex }); | ||
125 | - }, | ||
126 | - }); | ||
127 | - }); | ||
128 | - } | ||
129 | - | ||
130 | - onMounted(() => { | ||
131 | - initSortableTabs(); | ||
132 | - }); | ||
133 | - | ||
134 | return () => { | 87 | return () => { |
135 | const slots = { | 88 | const slots = { |
136 | default: () => renderTabs(), | 89 | default: () => renderTabs(), |
src/layouts/default/multitabs/types.ts
0 → 100644
1 | +import type { DropMenu } from '/@/components/Dropdown/index'; | ||
2 | +import type { RouteLocationNormalized } from 'vue-router'; | ||
3 | + | ||
4 | +export enum TabContentEnum { | ||
5 | + TAB_TYPE, | ||
6 | + EXTRA_TYPE, | ||
7 | +} | ||
8 | + | ||
9 | +export type { DropMenu }; | ||
10 | + | ||
11 | +export interface TabContentProps { | ||
12 | + tabItem: RouteLocationNormalized; | ||
13 | + type?: TabContentEnum; | ||
14 | + trigger?: ('click' | 'hover' | 'contextmenu')[]; | ||
15 | +} | ||
16 | + | ||
17 | +/** | ||
18 | + * @description: 右键:下拉菜单文字 | ||
19 | + */ | ||
20 | +export enum MenuEventEnum { | ||
21 | + // 刷新 | ||
22 | + REFRESH_PAGE, | ||
23 | + // 关闭当前 | ||
24 | + CLOSE_CURRENT, | ||
25 | + // 关闭左侧 | ||
26 | + CLOSE_LEFT, | ||
27 | + // 关闭右侧 | ||
28 | + CLOSE_RIGHT, | ||
29 | + // 关闭其他 | ||
30 | + CLOSE_OTHER, | ||
31 | + // 关闭所有 | ||
32 | + CLOSE_ALL, | ||
33 | + // 放大 | ||
34 | + SCALE, | ||
35 | +} |
src/layouts/default/multitabs/useMultipleTabs.ts
1 | -import { toRaw, ref } from 'vue'; | 1 | +import Sortable from 'sortablejs'; |
2 | +import { toRaw, ref, nextTick, onMounted } from 'vue'; | ||
3 | +import { RouteLocationNormalized } from 'vue-router'; | ||
4 | +import { useProjectSetting } from '/@/hooks/setting'; | ||
2 | import router from '/@/router'; | 5 | import router from '/@/router'; |
3 | -import { AppRouteRecordRaw } from '/@/router/types'; | ||
4 | -import { TabItem, tabStore } from '/@/store/modules/tab'; | 6 | +import { tabStore } from '/@/store/modules/tab'; |
7 | +import { isNullAndUnDef } from '/@/utils/is'; | ||
5 | 8 | ||
6 | -export function initAffixTabs() { | ||
7 | - const affixList = ref<TabItem[]>([]); | 9 | +export function initAffixTabs(): string[] { |
10 | + const affixList = ref<RouteLocationNormalized[]>([]); | ||
8 | /** | 11 | /** |
9 | * @description: Filter all fixed routes | 12 | * @description: Filter all fixed routes |
10 | */ | 13 | */ |
11 | - function filterAffixTabs(routes: AppRouteRecordRaw[]) { | ||
12 | - const tabs: TabItem[] = []; | 14 | + function filterAffixTabs(routes: RouteLocationNormalized[]) { |
15 | + const tabs: RouteLocationNormalized[] = []; | ||
13 | routes && | 16 | routes && |
14 | routes.forEach((route) => { | 17 | routes.forEach((route) => { |
15 | if (route.meta && route.meta.affix) { | 18 | if (route.meta && route.meta.affix) { |
16 | - tabs.push(toRaw(route) as TabItem); | 19 | + tabs.push(toRaw(route)); |
17 | } | 20 | } |
18 | }); | 21 | }); |
19 | return tabs; | 22 | return tabs; |
@@ -23,10 +26,14 @@ export function initAffixTabs() { | @@ -23,10 +26,14 @@ export function initAffixTabs() { | ||
23 | * @description: Set fixed tabs | 26 | * @description: Set fixed tabs |
24 | */ | 27 | */ |
25 | function addAffixTabs(): void { | 28 | function addAffixTabs(): void { |
26 | - const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as AppRouteRecordRaw[]); | 29 | + const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as RouteLocationNormalized[]); |
27 | affixList.value = affixTabs; | 30 | affixList.value = affixTabs; |
28 | for (const tab of affixTabs) { | 31 | for (const tab of affixTabs) { |
29 | - tabStore.commitAddTab(tab); | 32 | + tabStore.addTabAction(({ |
33 | + meta: tab.meta, | ||
34 | + name: tab.name, | ||
35 | + path: tab.path, | ||
36 | + } as unknown) as RouteLocationNormalized); | ||
30 | } | 37 | } |
31 | } | 38 | } |
32 | 39 | ||
@@ -37,3 +44,41 @@ export function initAffixTabs() { | @@ -37,3 +44,41 @@ export function initAffixTabs() { | ||
37 | } | 44 | } |
38 | return affixList.value.map((item) => item.meta?.title).filter(Boolean); | 45 | return affixList.value.map((item) => item.meta?.title).filter(Boolean); |
39 | } | 46 | } |
47 | + | ||
48 | +export function useTabsDrag(affixTextList: string[]) { | ||
49 | + const { multiTabsSetting } = useProjectSetting(); | ||
50 | + | ||
51 | + function initSortableTabs() { | ||
52 | + if (!multiTabsSetting.canDrag) return; | ||
53 | + nextTick(() => { | ||
54 | + const el = document.querySelectorAll( | ||
55 | + '.multiple-tabs .ant-tabs-nav > div' | ||
56 | + )?.[0] as HTMLElement; | ||
57 | + | ||
58 | + if (!el) return; | ||
59 | + Sortable.create(el, { | ||
60 | + animation: 500, | ||
61 | + delay: 400, | ||
62 | + delayOnTouchOnly: true, | ||
63 | + filter: (e: ChangeEvent) => { | ||
64 | + const text = e?.target?.innerText; | ||
65 | + if (!text) return false; | ||
66 | + return affixTextList.includes(text); | ||
67 | + }, | ||
68 | + onEnd: (evt) => { | ||
69 | + const { oldIndex, newIndex } = evt; | ||
70 | + | ||
71 | + if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) { | ||
72 | + return; | ||
73 | + } | ||
74 | + | ||
75 | + tabStore.commitSortTabs({ oldIndex, newIndex }); | ||
76 | + }, | ||
77 | + }); | ||
78 | + }); | ||
79 | + } | ||
80 | + | ||
81 | + onMounted(() => { | ||
82 | + initSortableTabs(); | ||
83 | + }); | ||
84 | +} |
src/layouts/default/multitabs/useTabDropdown.ts
1 | -import type { AppRouteRecordRaw } from '/@/router/types'; | ||
2 | -import type { TabContentProps } from './data'; | ||
3 | -import type { Ref } from 'vue'; | ||
4 | -import type { TabItem } from '/@/store/modules/tab'; | 1 | +import type { TabContentProps } from './types'; |
5 | import type { DropMenu } from '/@/components/Dropdown'; | 2 | import type { DropMenu } from '/@/components/Dropdown'; |
6 | 3 | ||
7 | -import { computed, unref } from 'vue'; | ||
8 | -import { TabContentEnum, MenuEventEnum, getActions } from './data'; | 4 | +import { computed, unref, reactive } from 'vue'; |
5 | +import { TabContentEnum, MenuEventEnum } from './types'; | ||
9 | import { tabStore } from '/@/store/modules/tab'; | 6 | import { tabStore } from '/@/store/modules/tab'; |
10 | -import { appStore } from '/@/store/modules/app'; | ||
11 | -import { PageEnum } from '/@/enums/pageEnum'; | ||
12 | -import { useGo, useRedo } from '/@/hooks/web/usePage'; | ||
13 | import router from '/@/router'; | 7 | import router from '/@/router'; |
14 | -import { useTabs, isInitUseTab } from '/@/hooks/web/useTabs'; | ||
15 | -import { RouteLocationRaw } from 'vue-router'; | 8 | +import { RouteLocationNormalized } from 'vue-router'; |
9 | +import { useTabs } from '/@/hooks/web/useTabs'; | ||
10 | +import { useI18n } from '/@/hooks/web/useI18n'; | ||
11 | +import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; | ||
12 | +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | ||
13 | +import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; | ||
16 | 14 | ||
17 | -const { initTabFn } = useTabs(); | 15 | +const { t } = useI18n(); |
18 | 16 | ||
19 | export function useTabDropdown(tabContentProps: TabContentProps) { | 17 | export function useTabDropdown(tabContentProps: TabContentProps) { |
20 | - const { currentRoute } = router; | ||
21 | - const redo = useRedo(); | ||
22 | - const go = useGo(); | ||
23 | - | ||
24 | - const isTabsRef = computed(() => tabContentProps.type === TabContentEnum.TAB_TYPE); | ||
25 | - const getCurrentTab: Ref<TabItem | AppRouteRecordRaw> = computed(() => { | ||
26 | - return unref(isTabsRef) | ||
27 | - ? tabContentProps.tabItem | ||
28 | - : ((unref(currentRoute) as any) as AppRouteRecordRaw); | 18 | + const state = reactive({ |
19 | + current: null as Nullable<RouteLocationNormalized>, | ||
20 | + currentIndex: 0, | ||
29 | }); | 21 | }); |
30 | 22 | ||
31 | - // Current tab list | ||
32 | - const getTabsState = computed(() => tabStore.getTabsState); | 23 | + const { currentRoute } = router; |
24 | + | ||
25 | + const { getShowMenu, setMenuSetting } = useMenuSetting(); | ||
26 | + const { getShowHeader, setHeaderSetting } = useHeaderSetting(); | ||
27 | + const { getShowQuick } = useMultipleTabSetting(); | ||
28 | + | ||
29 | + const isTabs = computed(() => | ||
30 | + !unref(getShowQuick) ? true : tabContentProps.type === TabContentEnum.TAB_TYPE | ||
31 | + ); | ||
32 | + | ||
33 | + const getCurrentTab = computed( | ||
34 | + (): RouteLocationNormalized => { | ||
35 | + return unref(isTabs) ? tabContentProps.tabItem : unref(currentRoute); | ||
36 | + } | ||
37 | + ); | ||
38 | + | ||
39 | + const getIsScale = computed(() => { | ||
40 | + return !unref(getShowMenu) && !unref(getShowHeader); | ||
41 | + }); | ||
33 | 42 | ||
34 | /** | 43 | /** |
35 | * @description: drop-down list | 44 | * @description: drop-down list |
36 | */ | 45 | */ |
37 | const getDropMenuList = computed(() => { | 46 | const getDropMenuList = computed(() => { |
38 | - const dropMenuList = getActions(); | ||
39 | - // Reset to initial state | ||
40 | - for (const item of dropMenuList) { | ||
41 | - item.disabled = false; | ||
42 | - } | ||
43 | - | ||
44 | - // No tab | ||
45 | - if (!unref(getTabsState) || unref(getTabsState).length <= 0) { | ||
46 | - return dropMenuList; | ||
47 | - } else if (unref(getTabsState).length === 1) { | ||
48 | - // Only one tab | ||
49 | - for (const item of dropMenuList) { | ||
50 | - if (item.event !== MenuEventEnum.REFRESH_PAGE) { | ||
51 | - item.disabled = true; | ||
52 | - } | ||
53 | - } | ||
54 | - return dropMenuList; | ||
55 | - } | ||
56 | if (!unref(getCurrentTab)) return; | 47 | if (!unref(getCurrentTab)) return; |
57 | - const { meta, path } = unref(getCurrentTab); | 48 | + const { meta } = unref(getCurrentTab); |
49 | + const { path } = unref(currentRoute); | ||
58 | 50 | ||
59 | // Refresh button | 51 | // Refresh button |
60 | - const curItem = tabStore.getCurrentContextMenuState; | ||
61 | - const index = tabStore.getCurrentContextMenuIndexState; | 52 | + const curItem = state.current; |
53 | + const index = state.currentIndex; | ||
62 | const refreshDisabled = curItem ? curItem.path !== path : true; | 54 | const refreshDisabled = curItem ? curItem.path !== path : true; |
63 | // Close left | 55 | // Close left |
64 | const closeLeftDisabled = index === 0; | 56 | const closeLeftDisabled = index === 0; |
65 | 57 | ||
58 | + const disabled = tabStore.getTabsState.length === 1; | ||
59 | + | ||
66 | // Close right | 60 | // Close right |
67 | - const closeRightDisabled = index === unref(getTabsState).length - 1; | ||
68 | - // Currently fixed tab | ||
69 | - // TODO PERf | ||
70 | - dropMenuList[0].disabled = unref(isTabsRef) ? refreshDisabled : false; | ||
71 | - if (meta && meta.affix) { | ||
72 | - dropMenuList[1].disabled = true; | 61 | + const closeRightDisabled = |
62 | + index === tabStore.getTabsState.length - 1 && tabStore.getLastDragEndIndexState >= 0; | ||
63 | + const dropMenuList: DropMenu[] = [ | ||
64 | + { | ||
65 | + icon: 'ant-design:reload-outlined', | ||
66 | + event: MenuEventEnum.REFRESH_PAGE, | ||
67 | + text: t('layout.multipleTab.redo'), | ||
68 | + disabled: refreshDisabled, | ||
69 | + }, | ||
70 | + { | ||
71 | + icon: 'ant-design:close-outlined', | ||
72 | + event: MenuEventEnum.CLOSE_CURRENT, | ||
73 | + text: t('layout.multipleTab.close'), | ||
74 | + disabled: meta?.affix || disabled, | ||
75 | + divider: true, | ||
76 | + }, | ||
77 | + { | ||
78 | + icon: 'ant-design:pic-left-outlined', | ||
79 | + event: MenuEventEnum.CLOSE_LEFT, | ||
80 | + text: t('layout.multipleTab.closeLeft'), | ||
81 | + disabled: closeLeftDisabled, | ||
82 | + divider: false, | ||
83 | + }, | ||
84 | + { | ||
85 | + icon: 'ant-design:pic-right-outlined', | ||
86 | + event: MenuEventEnum.CLOSE_RIGHT, | ||
87 | + text: t('layout.multipleTab.closeRight'), | ||
88 | + disabled: closeRightDisabled, | ||
89 | + divider: true, | ||
90 | + }, | ||
91 | + { | ||
92 | + icon: 'ant-design:pic-center-outlined', | ||
93 | + event: MenuEventEnum.CLOSE_OTHER, | ||
94 | + text: t('layout.multipleTab.closeOther'), | ||
95 | + disabled: disabled, | ||
96 | + }, | ||
97 | + { | ||
98 | + icon: 'ant-design:line-outlined', | ||
99 | + event: MenuEventEnum.CLOSE_ALL, | ||
100 | + text: t('layout.multipleTab.closeAll'), | ||
101 | + disabled: disabled, | ||
102 | + }, | ||
103 | + ]; | ||
104 | + | ||
105 | + if (!unref(isTabs)) { | ||
106 | + const isScale = unref(getIsScale); | ||
107 | + dropMenuList.unshift({ | ||
108 | + icon: isScale ? 'codicon:screen-normal' : 'codicon:screen-full', | ||
109 | + event: MenuEventEnum.SCALE, | ||
110 | + text: isScale ? t('layout.multipleTab.putAway') : t('layout.multipleTab.unfold'), | ||
111 | + disabled: false, | ||
112 | + }); | ||
73 | } | 113 | } |
74 | - dropMenuList[2].disabled = closeLeftDisabled; | ||
75 | - dropMenuList[3].disabled = closeRightDisabled; | ||
76 | 114 | ||
77 | return dropMenuList; | 115 | return dropMenuList; |
78 | }); | 116 | }); |
79 | 117 | ||
80 | - /** | ||
81 | - * @description: Jump to page when closing all pages | ||
82 | - */ | ||
83 | - function gotoPage() { | ||
84 | - const len = unref(getTabsState).length; | ||
85 | - const { path } = unref(currentRoute); | ||
86 | - | ||
87 | - let toPath: PageEnum | string = PageEnum.BASE_HOME; | ||
88 | - | ||
89 | - if (len > 0) { | ||
90 | - const page = unref(getTabsState)[len - 1]; | ||
91 | - const p = page.fullPath || page.path; | ||
92 | - if (p) { | ||
93 | - toPath = p; | ||
94 | - } | ||
95 | - } | ||
96 | - // Jump to the current page and report an error | ||
97 | - path !== toPath && go(toPath as PageEnum, true); | ||
98 | - } | ||
99 | - | ||
100 | - function isGotoPage(currentTab?: TabItem) { | ||
101 | - const { path } = unref(currentRoute); | ||
102 | - const currentPath = (currentTab || unref(getCurrentTab)).path; | ||
103 | - // Not the current tab, when you close the left/right side, you need to jump to the page | ||
104 | - if (path !== currentPath) { | ||
105 | - go(currentPath as PageEnum, true); | ||
106 | - } | ||
107 | - } | ||
108 | - function refreshPage(tabItem?: TabItem) { | ||
109 | - try { | ||
110 | - tabStore.commitCloseTabKeepAlive(tabItem || unref(getCurrentTab)); | ||
111 | - } catch (error) {} | ||
112 | - redo(); | ||
113 | - } | ||
114 | - | ||
115 | - function closeAll() { | ||
116 | - tabStore.commitCloseAllTab(); | ||
117 | - gotoPage(); | ||
118 | - } | ||
119 | - | ||
120 | - function closeLeft(tabItem?: TabItem) { | ||
121 | - tabStore.closeLeftTabAction(tabItem || unref(getCurrentTab)); | ||
122 | - isGotoPage(tabItem); | ||
123 | - } | ||
124 | - | ||
125 | - function closeRight(tabItem?: TabItem) { | ||
126 | - tabStore.closeRightTabAction(tabItem || unref(getCurrentTab)); | ||
127 | - isGotoPage(tabItem); | ||
128 | - } | ||
129 | - | ||
130 | - function closeOther(tabItem?: TabItem) { | ||
131 | - tabStore.closeOtherTabAction(tabItem || unref(getCurrentTab)); | ||
132 | - isGotoPage(tabItem); | ||
133 | - } | 118 | + const getTrigger = computed(() => { |
119 | + return unref(isTabs) ? ['contextmenu'] : ['click']; | ||
120 | + }); | ||
134 | 121 | ||
135 | - function closeCurrent(tabItem?: TabItem) { | ||
136 | - closeTab(unref(tabItem || unref(getCurrentTab))); | 122 | + function handleContextMenu(tabItem: RouteLocationNormalized) { |
123 | + return (e: Event) => { | ||
124 | + if (!tabItem) return; | ||
125 | + e?.preventDefault(); | ||
126 | + const index = tabStore.getTabsState.findIndex((tab) => tab.path === tabItem.path); | ||
127 | + state.current = tabItem; | ||
128 | + state.currentIndex = index; | ||
129 | + }; | ||
137 | } | 130 | } |
138 | 131 | ||
139 | function scaleScreen() { | 132 | function scaleScreen() { |
140 | - const { | ||
141 | - headerSetting: { show: showHeader }, | ||
142 | - menuSetting: { show: showMenu }, | ||
143 | - } = appStore.getProjectConfig; | ||
144 | - const isScale = !showHeader && !showMenu; | ||
145 | - appStore.commitProjectConfigState({ | ||
146 | - headerSetting: { show: isScale }, | ||
147 | - menuSetting: { show: isScale }, | 133 | + const isScale = !unref(getShowMenu) && !unref(getShowHeader); |
134 | + setMenuSetting({ | ||
135 | + show: isScale, | ||
148 | }); | 136 | }); |
149 | - } | ||
150 | - | ||
151 | - if (!isInitUseTab) { | ||
152 | - initTabFn({ | ||
153 | - refreshPageFn: refreshPage, | ||
154 | - closeAllFn: closeAll, | ||
155 | - closeCurrentFn: closeCurrent, | ||
156 | - closeLeftFn: closeLeft, | ||
157 | - closeOtherFn: closeOther, | ||
158 | - closeRightFn: closeRight, | 137 | + setHeaderSetting({ |
138 | + show: isScale, | ||
159 | }); | 139 | }); |
160 | } | 140 | } |
161 | 141 | ||
162 | // Handle right click event | 142 | // Handle right click event |
163 | function handleMenuEvent(menu: DropMenu): void { | 143 | function handleMenuEvent(menu: DropMenu): void { |
144 | + const { refreshPage, closeAll, closeCurrent, closeLeft, closeOther, closeRight } = useTabs(); | ||
164 | const { event } = menu; | 145 | const { event } = menu; |
165 | - | ||
166 | switch (event) { | 146 | switch (event) { |
167 | case MenuEventEnum.SCALE: | 147 | case MenuEventEnum.SCALE: |
168 | scaleScreen(); | 148 | scaleScreen(); |
@@ -193,51 +173,5 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | @@ -193,51 +173,5 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | ||
193 | break; | 173 | break; |
194 | } | 174 | } |
195 | } | 175 | } |
196 | - return { getDropMenuList, handleMenuEvent }; | ||
197 | -} | ||
198 | - | ||
199 | -export function getObj(tabItem: TabItem) { | ||
200 | - const { params, path, query } = tabItem; | ||
201 | - return { | ||
202 | - params: params || {}, | ||
203 | - path, | ||
204 | - query: query || {}, | ||
205 | - }; | ||
206 | -} | ||
207 | - | ||
208 | -export function closeTab(closedTab: TabItem | AppRouteRecordRaw) { | ||
209 | - const { currentRoute, replace } = router; | ||
210 | - // Current tab list | ||
211 | - const getTabsState = computed(() => tabStore.getTabsState); | ||
212 | - | ||
213 | - const { path } = unref(currentRoute); | ||
214 | - if (path !== closedTab.path) { | ||
215 | - // Closed is not the activation tab | ||
216 | - tabStore.commitCloseTab(closedTab); | ||
217 | - return; | ||
218 | - } | ||
219 | - | ||
220 | - // Closed is activated atb | ||
221 | - let toObj: RouteLocationRaw = {}; | ||
222 | - | ||
223 | - const index = unref(getTabsState).findIndex((item) => item.path === path); | ||
224 | - | ||
225 | - // If the current is the leftmost tab | ||
226 | - if (index === 0) { | ||
227 | - // There is only one tab, then jump to the homepage, otherwise jump to the right tab | ||
228 | - if (unref(getTabsState).length === 1) { | ||
229 | - toObj = PageEnum.BASE_HOME; | ||
230 | - } else { | ||
231 | - // Jump to the right tab | ||
232 | - const page = unref(getTabsState)[index + 1]; | ||
233 | - toObj = getObj(page); | ||
234 | - } | ||
235 | - } else { | ||
236 | - // Close the current tab | ||
237 | - const page = unref(getTabsState)[index - 1]; | ||
238 | - toObj = getObj(page); | ||
239 | - } | ||
240 | - const route = (unref(currentRoute) as unknown) as AppRouteRecordRaw; | ||
241 | - tabStore.commitCloseTab(route); | ||
242 | - replace(toObj); | 176 | + return { getDropMenuList, handleMenuEvent, handleContextMenu, getTrigger, isTabs }; |
243 | } | 177 | } |
src/layouts/iframe/index.vue
1 | <template> | 1 | <template> |
2 | <template v-for="frame in getFramePages" :key="frame.path"> | 2 | <template v-for="frame in getFramePages" :key="frame.path"> |
3 | <FramePage | 3 | <FramePage |
4 | - v-if="frame.meta.frameSrc && hasRenderFrame(frame.path)" | 4 | + v-if="frame.meta.frameSrc && hasRenderFrame(frame.name)" |
5 | v-show="showIframe(frame)" | 5 | v-show="showIframe(frame)" |
6 | :frameSrc="frame.meta.frameSrc" | 6 | :frameSrc="frame.meta.frameSrc" |
7 | /> | 7 | /> |
src/layouts/iframe/useFrameKeepAlive.ts
@@ -23,7 +23,7 @@ export function useFrameKeepAlive() { | @@ -23,7 +23,7 @@ export function useFrameKeepAlive() { | ||
23 | const getOpenTabList = computed((): string[] => { | 23 | const getOpenTabList = computed((): string[] => { |
24 | return tabStore.getTabsState.reduce((prev: string[], next) => { | 24 | return tabStore.getTabsState.reduce((prev: string[], next) => { |
25 | if (next.meta && Reflect.has(next.meta, 'frameSrc')) { | 25 | if (next.meta && Reflect.has(next.meta, 'frameSrc')) { |
26 | - prev.push(next.path!); | 26 | + prev.push(next.name as string); |
27 | } | 27 | } |
28 | return prev; | 28 | return prev; |
29 | }, []); | 29 | }, []); |
@@ -45,11 +45,14 @@ export function useFrameKeepAlive() { | @@ -45,11 +45,14 @@ export function useFrameKeepAlive() { | ||
45 | } | 45 | } |
46 | 46 | ||
47 | function showIframe(item: AppRouteRecordRaw) { | 47 | function showIframe(item: AppRouteRecordRaw) { |
48 | - return item.path === unref(currentRoute).path; | 48 | + return item.name === unref(currentRoute).name; |
49 | } | 49 | } |
50 | 50 | ||
51 | - function hasRenderFrame(path: string) { | ||
52 | - return unref(getShowMultipleTab) ? unref(getOpenTabList).includes(path) : true; | 51 | + function hasRenderFrame(name: string) { |
52 | + if (!unref(getShowMultipleTab)) { | ||
53 | + return true; | ||
54 | + } | ||
55 | + return unref(getOpenTabList).includes(name); | ||
53 | } | 56 | } |
54 | return { hasRenderFrame, getFramePages, showIframe, getAllFramePages }; | 57 | return { hasRenderFrame, getFramePages, showIframe, getAllFramePages }; |
55 | } | 58 | } |
src/layouts/page/index.tsx deleted
100644 → 0
1 | -import type { FunctionalComponent } from 'vue'; | ||
2 | - | ||
3 | -import { computed, defineComponent, unref, Transition, KeepAlive } from 'vue'; | ||
4 | -import { RouterView, RouteLocation } from 'vue-router'; | ||
5 | - | ||
6 | -import FrameLayout from '/@/layouts/iframe/index.vue'; | ||
7 | - | ||
8 | -import { useTransition } from './useTransition'; | ||
9 | -import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | ||
10 | -import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
11 | -import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; | ||
12 | - | ||
13 | -import { tabStore } from '/@/store/modules/tab'; | ||
14 | -import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; | ||
15 | - | ||
16 | -interface DefaultContext { | ||
17 | - Component: FunctionalComponent; | ||
18 | - route: RouteLocation; | ||
19 | -} | ||
20 | - | ||
21 | -export default defineComponent({ | ||
22 | - name: 'PageLayout', | ||
23 | - setup() { | ||
24 | - const { getShowMenu } = useMenuSetting(); | ||
25 | - | ||
26 | - const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting(); | ||
27 | - | ||
28 | - const { getBasicTransition, getEnableTransition } = useTransitionSetting(); | ||
29 | - | ||
30 | - const { getMax } = useMultipleTabSetting(); | ||
31 | - | ||
32 | - const transitionEvent = useTransition(); | ||
33 | - | ||
34 | - const openCacheRef = computed(() => unref(getOpenKeepAlive) && unref(getShowMenu)); | ||
35 | - | ||
36 | - const getCacheTabsRef = computed(() => tabStore.getKeepAliveTabsState as string[]); | ||
37 | - | ||
38 | - return () => { | ||
39 | - return ( | ||
40 | - <div> | ||
41 | - <RouterView> | ||
42 | - {{ | ||
43 | - default: ({ Component, route }: DefaultContext) => { | ||
44 | - // No longer show animations that are already in the tab | ||
45 | - const cacheTabs = unref(getCacheTabsRef); | ||
46 | - const isInCache = cacheTabs.includes(route.name as string); | ||
47 | - const name = isInCache && route.meta.inTab ? 'fade-slide' : null; | ||
48 | - | ||
49 | - const renderComp = () => <Component key={route.fullPath} />; | ||
50 | - | ||
51 | - const PageContent = unref(openCacheRef) ? ( | ||
52 | - <KeepAlive max={unref(getMax)} include={cacheTabs}> | ||
53 | - {renderComp()} | ||
54 | - </KeepAlive> | ||
55 | - ) : ( | ||
56 | - renderComp() | ||
57 | - ); | ||
58 | - | ||
59 | - return unref(getEnableTransition) ? ( | ||
60 | - <Transition | ||
61 | - {...transitionEvent} | ||
62 | - name={name || route.meta.transitionName || unref(getBasicTransition)} | ||
63 | - mode="out-in" | ||
64 | - appear={true} | ||
65 | - > | ||
66 | - {() => PageContent} | ||
67 | - </Transition> | ||
68 | - ) : ( | ||
69 | - PageContent | ||
70 | - ); | ||
71 | - }, | ||
72 | - }} | ||
73 | - </RouterView> | ||
74 | - {unref(getCanEmbedIFramePage) && <FrameLayout />} | ||
75 | - </div> | ||
76 | - ); | ||
77 | - }; | ||
78 | - }, | ||
79 | -}); |
src/layouts/page/index.vue
0 → 100644
1 | +<template> | ||
2 | + <ParentLayout :isPage="true" /> | ||
3 | + <FrameLayout v-if="getCanEmbedIFramePage" /> | ||
4 | +</template> | ||
5 | +<script lang="ts"> | ||
6 | + import { defineComponent } from 'vue'; | ||
7 | + | ||
8 | + import FrameLayout from '/@/layouts/iframe/index.vue'; | ||
9 | + | ||
10 | + import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
11 | + | ||
12 | + import ParentLayout from '/@/layouts/parent/index.vue'; | ||
13 | + export default defineComponent({ | ||
14 | + components: { ParentLayout, FrameLayout }, | ||
15 | + setup() { | ||
16 | + const { getCanEmbedIFramePage } = useRootSetting(); | ||
17 | + | ||
18 | + return { getCanEmbedIFramePage }; | ||
19 | + }, | ||
20 | + }); | ||
21 | +</script> |
src/layouts/parent/index.vue
0 → 100644
1 | +<!-- | ||
2 | + * @Description: The reason is that tsx will report warnings under multi-level nesting. | ||
3 | +--> | ||
4 | +<template> | ||
5 | + <div> | ||
6 | + <router-view> | ||
7 | + <template #default="{ Component, route }"> | ||
8 | + <transition v-bind="transitionEvent" :name="getName(route)" mode="out-in" appear> | ||
9 | + <keep-alive v-if="openCache" :include="getCaches"> | ||
10 | + <component :max="getMax" :is="Component" :key="route.fullPath" /> | ||
11 | + </keep-alive> | ||
12 | + <component v-else :max="getMax" :is="Component" :key="route.fullPath" /> | ||
13 | + </transition> | ||
14 | + </template> | ||
15 | + </router-view> | ||
16 | + </div> | ||
17 | +</template> | ||
18 | +<script lang="ts"> | ||
19 | + import { computed, defineComponent, unref } from 'vue'; | ||
20 | + import { RouteLocationNormalized } from 'vue-router'; | ||
21 | + | ||
22 | + import { useTransition } from './useTransition'; | ||
23 | + import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | ||
24 | + import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
25 | + import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; | ||
26 | + | ||
27 | + import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; | ||
28 | + import { useCache } from './useCache'; | ||
29 | + | ||
30 | + export default defineComponent({ | ||
31 | + props: { | ||
32 | + isPage: { | ||
33 | + type: Boolean, | ||
34 | + }, | ||
35 | + }, | ||
36 | + setup(props) { | ||
37 | + const { getCaches } = useCache(props.isPage); | ||
38 | + | ||
39 | + const { getShowMenu } = useMenuSetting(); | ||
40 | + | ||
41 | + const { getOpenKeepAlive } = useRootSetting(); | ||
42 | + | ||
43 | + const { getBasicTransition, getEnableTransition } = useTransitionSetting(); | ||
44 | + | ||
45 | + const { getMax } = useMultipleTabSetting(); | ||
46 | + | ||
47 | + const transitionEvent = useTransition(); | ||
48 | + | ||
49 | + const openCache = computed(() => unref(getOpenKeepAlive) && unref(getShowMenu)); | ||
50 | + | ||
51 | + function getName(route: RouteLocationNormalized) { | ||
52 | + if (!unref(getEnableTransition)) { | ||
53 | + return null; | ||
54 | + } | ||
55 | + const cacheTabs = unref(getCaches); | ||
56 | + const isInCache = cacheTabs.includes(route.name as string); | ||
57 | + const name = isInCache && route.meta.inTab ? 'fade-slide' : null; | ||
58 | + | ||
59 | + return name || route.meta.transitionName || unref(getBasicTransition); | ||
60 | + } | ||
61 | + | ||
62 | + return { | ||
63 | + getCaches, | ||
64 | + getMax, | ||
65 | + transitionEvent, | ||
66 | + getBasicTransition, | ||
67 | + getName, | ||
68 | + openCache, | ||
69 | + getEnableTransition, | ||
70 | + }; | ||
71 | + }, | ||
72 | + }); | ||
73 | +</script> |
src/layouts/parent/useCache.ts
0 → 100644
1 | +import { computed, ref, unref } from 'vue'; | ||
2 | +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
3 | +import { tryTsxEmit } from '/@/utils/helper/vueHelper'; | ||
4 | +import { tabStore, PAGE_LAYOUT_KEY } from '/@/store/modules/tab'; | ||
5 | + | ||
6 | +import { useRouter } from 'vue-router'; | ||
7 | + | ||
8 | +const ParentLayoutName = 'ParentLayout'; | ||
9 | +export function useCache(isPage: boolean) { | ||
10 | + const name = ref(''); | ||
11 | + const { currentRoute } = useRouter(); | ||
12 | + | ||
13 | + tryTsxEmit((instance: any) => { | ||
14 | + const routeName = instance.ctx.$options.name; | ||
15 | + | ||
16 | + if (routeName && ![ParentLayoutName].includes(routeName)) { | ||
17 | + name.value = routeName; | ||
18 | + } else { | ||
19 | + const matched = currentRoute.value.matched; | ||
20 | + const len = matched.length; | ||
21 | + if (len < 2) return; | ||
22 | + name.value = matched[len - 2].name as string; | ||
23 | + } | ||
24 | + }); | ||
25 | + const { getOpenKeepAlive } = useRootSetting(); | ||
26 | + | ||
27 | + const getCaches = computed((): string[] => { | ||
28 | + if (!unref(getOpenKeepAlive)) { | ||
29 | + return []; | ||
30 | + } | ||
31 | + const cached = tabStore.getCachedMapState; | ||
32 | + | ||
33 | + if (isPage) { | ||
34 | + // page Layout | ||
35 | + // not parent layout | ||
36 | + return cached.get(PAGE_LAYOUT_KEY) || []; | ||
37 | + } | ||
38 | + | ||
39 | + const cacheSet = new Set<string>(); | ||
40 | + cacheSet.add(unref(name)); | ||
41 | + | ||
42 | + const list = cached.get(unref(name)); | ||
43 | + if (!list) { | ||
44 | + return Array.from(cacheSet); | ||
45 | + } | ||
46 | + list.forEach((item) => { | ||
47 | + cacheSet.add(item); | ||
48 | + }); | ||
49 | + return Array.from(cacheSet); | ||
50 | + }); | ||
51 | + return { getCaches }; | ||
52 | +} |
src/layouts/page/useTransition.ts renamed to src/layouts/parent/useTransition.ts
src/locales/lang/en/component/form.ts
@@ -4,8 +4,8 @@ export default { | @@ -4,8 +4,8 @@ export default { | ||
4 | putAway: 'Put away', | 4 | putAway: 'Put away', |
5 | unfold: 'Unfold', | 5 | unfold: 'Unfold', |
6 | 6 | ||
7 | - input: 'Please Input', | ||
8 | - choose: 'Please Choose', | 7 | + input: 'Please Input ', |
8 | + choose: 'Please Choose ', | ||
9 | 9 | ||
10 | maxTip: 'The number of characters should be less than {0}', | 10 | maxTip: 'The number of characters should be less than {0}', |
11 | }; | 11 | }; |
src/locales/lang/en/layout/header.ts
@@ -15,4 +15,6 @@ export default { | @@ -15,4 +15,6 @@ export default { | ||
15 | lockScreen: 'Lock screen', | 15 | lockScreen: 'Lock screen', |
16 | lockScreenBtn: 'Locking', | 16 | lockScreenBtn: 'Locking', |
17 | notLockScreenPassword: 'No password lock screen', | 17 | notLockScreenPassword: 'No password lock screen', |
18 | + | ||
19 | + home: 'Home', | ||
18 | }; | 20 | }; |
src/locales/lang/en/routes/demo/level.ts
0 → 100644
src/locales/lang/zh_CN/layout/header.ts
src/locales/lang/zh_CN/routes/demo/feat.ts
src/locales/lang/zh_CN/routes/demo/level.ts
0 → 100644
src/router/constant.ts
1 | import type { AppRouteRecordRaw } from '/@/router/types'; | 1 | import type { AppRouteRecordRaw } from '/@/router/types'; |
2 | +import ParentLayout from '/@/layouts/parent/index.vue'; | ||
2 | 3 | ||
3 | const EXCEPTION_COMPONENT = () => import('../views/sys/exception/Exception'); | 4 | const EXCEPTION_COMPONENT = () => import('../views/sys/exception/Exception'); |
4 | 5 | ||
5 | /** | 6 | /** |
6 | * @description: default layout | 7 | * @description: default layout |
7 | */ | 8 | */ |
8 | -export const DEFAULT_LAYOUT_COMPONENT = () => import('/@/layouts/default/index'); | 9 | +export const LAYOUT = () => import('/@/layouts/default/index'); |
9 | 10 | ||
10 | /** | 11 | /** |
11 | * @description: page-layout | 12 | * @description: page-layout |
12 | */ | 13 | */ |
13 | -export const PAGE_LAYOUT_COMPONENT = () => import('/@/layouts/page/index'); | 14 | +export const PAGE_LAYOUT_COMPONENT = () => import('/@/layouts/page/index.vue'); |
15 | + | ||
16 | +/** | ||
17 | + * @description: page-layout | ||
18 | + */ | ||
19 | +export const getParentLayout = (name: string) => { | ||
20 | + return () => | ||
21 | + new Promise((resolve) => { | ||
22 | + resolve({ | ||
23 | + ...ParentLayout, | ||
24 | + name, | ||
25 | + }); | ||
26 | + }); | ||
27 | +}; | ||
14 | 28 | ||
15 | // 404 on a page | 29 | // 404 on a page |
16 | export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = { | 30 | export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = { |
@@ -23,12 +37,25 @@ export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = { | @@ -23,12 +37,25 @@ export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = { | ||
23 | }, | 37 | }, |
24 | }; | 38 | }; |
25 | 39 | ||
40 | +export const REDIRECT_NAME = 'Redirect'; | ||
41 | + | ||
26 | export const REDIRECT_ROUTE: AppRouteRecordRaw = { | 42 | export const REDIRECT_ROUTE: AppRouteRecordRaw = { |
27 | - path: '/redirect/:path(.*)*', | ||
28 | - name: 'Redirect', | ||
29 | - component: () => import('/@/views/sys/redirect/index.vue'), | 43 | + path: '/redirect', |
44 | + name: REDIRECT_NAME, | ||
45 | + component: LAYOUT, | ||
30 | meta: { | 46 | meta: { |
31 | - title: 'Redirect', | 47 | + title: REDIRECT_NAME, |
32 | hideBreadcrumb: true, | 48 | hideBreadcrumb: true, |
33 | }, | 49 | }, |
50 | + children: [ | ||
51 | + { | ||
52 | + path: '/redirect/:path(.*)', | ||
53 | + name: REDIRECT_NAME, | ||
54 | + component: () => import('/@/views/sys/redirect/index.vue'), | ||
55 | + meta: { | ||
56 | + title: REDIRECT_NAME, | ||
57 | + hideBreadcrumb: true, | ||
58 | + }, | ||
59 | + }, | ||
60 | + ], | ||
34 | }; | 61 | }; |
src/router/guard/index.ts
@@ -8,17 +8,19 @@ import { createPageLoadingGuard } from './pageLoadingGuard'; | @@ -8,17 +8,19 @@ import { createPageLoadingGuard } from './pageLoadingGuard'; | ||
8 | 8 | ||
9 | import { useGlobSetting, useProjectSetting } from '/@/hooks/setting'; | 9 | import { useGlobSetting, useProjectSetting } from '/@/hooks/setting'; |
10 | 10 | ||
11 | -import { getIsOpenTab, setCurrentTo } from '/@/utils/helper/routeHelper'; | 11 | +import { getIsOpenTab, getRoute } from '/@/router/helper/routeHelper'; |
12 | import { setTitle } from '/@/utils/browser'; | 12 | import { setTitle } from '/@/utils/browser'; |
13 | import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel'; | 13 | import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel'; |
14 | 14 | ||
15 | import { tabStore } from '/@/store/modules/tab'; | 15 | import { tabStore } from '/@/store/modules/tab'; |
16 | import { useI18n } from '/@/hooks/web/useI18n'; | 16 | import { useI18n } from '/@/hooks/web/useI18n'; |
17 | +import { REDIRECT_NAME } from '/@/router/constant'; | ||
17 | 18 | ||
18 | const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting(); | 19 | const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting(); |
19 | const globSetting = useGlobSetting(); | 20 | const globSetting = useGlobSetting(); |
21 | + | ||
20 | export function createGuard(router: Router) { | 22 | export function createGuard(router: Router) { |
21 | - let axiosCanceler: AxiosCanceler | null; | 23 | + let axiosCanceler: Nullable<AxiosCanceler>; |
22 | if (removeAllHttpPending) { | 24 | if (removeAllHttpPending) { |
23 | axiosCanceler = new AxiosCanceler(); | 25 | axiosCanceler = new AxiosCanceler(); |
24 | } | 26 | } |
@@ -30,15 +32,7 @@ export function createGuard(router: Router) { | @@ -30,15 +32,7 @@ export function createGuard(router: Router) { | ||
30 | to.meta.inTab = isOpen; | 32 | to.meta.inTab = isOpen; |
31 | 33 | ||
32 | // Notify routing changes | 34 | // Notify routing changes |
33 | - const { fullPath, path, query, params, name, meta } = to; | ||
34 | - tabStore.commitLastChangeRouteState({ | ||
35 | - fullPath, | ||
36 | - path, | ||
37 | - query, | ||
38 | - params, | ||
39 | - name, | ||
40 | - meta, | ||
41 | - } as any); | 35 | + tabStore.commitLastChangeRouteState(getRoute(to)); |
42 | 36 | ||
43 | try { | 37 | try { |
44 | if (closeMessageOnSwitch) { | 38 | if (closeMessageOnSwitch) { |
@@ -50,14 +44,13 @@ export function createGuard(router: Router) { | @@ -50,14 +44,13 @@ export function createGuard(router: Router) { | ||
50 | } catch (error) { | 44 | } catch (error) { |
51 | console.warn('basic guard error:' + error); | 45 | console.warn('basic guard error:' + error); |
52 | } | 46 | } |
53 | - setCurrentTo(to); | ||
54 | return true; | 47 | return true; |
55 | }); | 48 | }); |
56 | 49 | ||
57 | router.afterEach((to) => { | 50 | router.afterEach((to) => { |
58 | const { t } = useI18n(); | 51 | const { t } = useI18n(); |
59 | // change html title | 52 | // change html title |
60 | - to.name !== 'Redirect' && setTitle(t(to.meta.title), globSetting.title); | 53 | + to.name !== REDIRECT_NAME && setTitle(t(to.meta.title), globSetting.title); |
61 | }); | 54 | }); |
62 | createProgressGuard(router); | 55 | createProgressGuard(router); |
63 | createPermissionGuard(router); | 56 | createPermissionGuard(router); |
src/router/guard/pageLoadingGuard.ts
@@ -2,7 +2,7 @@ import type { Router } from 'vue-router'; | @@ -2,7 +2,7 @@ import type { Router } from 'vue-router'; | ||
2 | import { tabStore } from '/@/store/modules/tab'; | 2 | import { tabStore } from '/@/store/modules/tab'; |
3 | import { appStore } from '/@/store/modules/app'; | 3 | import { appStore } from '/@/store/modules/app'; |
4 | import { userStore } from '/@/store/modules/user'; | 4 | import { userStore } from '/@/store/modules/user'; |
5 | -import { getParams } from '/@/utils/helper/routeHelper'; | 5 | +import { getParams } from '/@/router/helper/routeHelper'; |
6 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; | 6 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; |
7 | import { unref } from 'vue'; | 7 | import { unref } from 'vue'; |
8 | 8 | ||
@@ -14,6 +14,7 @@ export function createPageLoadingGuard(router: Router) { | @@ -14,6 +14,7 @@ export function createPageLoadingGuard(router: Router) { | ||
14 | if (!userStore.getTokenState) { | 14 | if (!userStore.getTokenState) { |
15 | return true; | 15 | return true; |
16 | } | 16 | } |
17 | + | ||
17 | if (!unref(getEnableTransition) && unref(getOpenPageLoading)) { | 18 | if (!unref(getEnableTransition) && unref(getOpenPageLoading)) { |
18 | appStore.commitPageLoadingState(true); | 19 | appStore.commitPageLoadingState(true); |
19 | return true; | 20 | return true; |
src/router/guard/permissionGuard.ts
@@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; | @@ -7,7 +7,7 @@ import { PageEnum } from '/@/enums/pageEnum'; | ||
7 | import { getToken } from '/@/utils/auth'; | 7 | import { getToken } from '/@/utils/auth'; |
8 | 8 | ||
9 | import { PAGE_NOT_FOUND_ROUTE } from '/@/router/constant'; | 9 | import { PAGE_NOT_FOUND_ROUTE } from '/@/router/constant'; |
10 | -import { RootRoute } from '../routes/index'; | 10 | +// import { RootRoute } from '../routes/index'; |
11 | 11 | ||
12 | const LOGIN_PATH = PageEnum.BASE_LOGIN; | 12 | const LOGIN_PATH = PageEnum.BASE_LOGIN; |
13 | 13 | ||
@@ -59,7 +59,8 @@ export function createPermissionGuard(router: Router) { | @@ -59,7 +59,8 @@ export function createPermissionGuard(router: Router) { | ||
59 | } | 59 | } |
60 | const routes = await permissionStore.buildRoutesAction(); | 60 | const routes = await permissionStore.buildRoutesAction(); |
61 | routes.forEach((route) => { | 61 | routes.forEach((route) => { |
62 | - router.addRoute(RootRoute.name!, route as RouteRecordRaw); | 62 | + // router.addRoute(RootRoute.name!, route as RouteRecordRaw); |
63 | + router.addRoute(route as RouteRecordRaw); | ||
63 | }); | 64 | }); |
64 | 65 | ||
65 | const redirectPath = (from.query.redirect || to.path) as string; | 66 | const redirectPath = (from.query.redirect || to.path) as string; |
src/router/guard/progressGuard.ts
@@ -9,9 +9,6 @@ import { unref } from 'vue'; | @@ -9,9 +9,6 @@ import { unref } from 'vue'; | ||
9 | const { getOpenNProgress } = useTransitionSetting(); | 9 | const { getOpenNProgress } = useTransitionSetting(); |
10 | 10 | ||
11 | export function createProgressGuard(router: Router) { | 11 | export function createProgressGuard(router: Router) { |
12 | - // NProgress.inc(0.1); | ||
13 | - // NProgress.configure({ easing: 'ease', speed: 200, showSpinner: false }); | ||
14 | - | ||
15 | router.beforeEach(async (to) => { | 12 | router.beforeEach(async (to) => { |
16 | !to.meta.inTab && unref(getOpenNProgress) && NProgress.start(); | 13 | !to.meta.inTab && unref(getOpenNProgress) && NProgress.start(); |
17 | return true; | 14 | return true; |
src/router/helper/dynamicImport.ts
0 → 100644
src/utils/helper/menuHelper.ts renamed to src/router/helper/menuHelper.ts
1 | -import { AppRouteModule, RouteModule } from '/@/router/types.d'; | 1 | +import { AppRouteModule } from '/@/router/types.d'; |
2 | import type { MenuModule, Menu, AppRouteRecordRaw } from '/@/router/types'; | 2 | import type { MenuModule, Menu, AppRouteRecordRaw } from '/@/router/types'; |
3 | 3 | ||
4 | -import { findPath, forEach, treeMap, treeToList } from './treeHelper'; | 4 | +import { findPath, forEach, treeMap, treeToList } from '/@/utils/helper/treeHelper'; |
5 | import { cloneDeep } from 'lodash-es'; | 5 | import { cloneDeep } from 'lodash-es'; |
6 | 6 | ||
7 | export function getAllParentPath(treeData: any[], path: string) { | 7 | export function getAllParentPath(treeData: any[], path: string) { |
@@ -48,12 +48,11 @@ export function transformRouteToMenu(routeModList: AppRouteModule[]) { | @@ -48,12 +48,11 @@ export function transformRouteToMenu(routeModList: AppRouteModule[]) { | ||
48 | const cloneRouteModList = cloneDeep(routeModList); | 48 | const cloneRouteModList = cloneDeep(routeModList); |
49 | const routeList: AppRouteRecordRaw[] = []; | 49 | const routeList: AppRouteRecordRaw[] = []; |
50 | cloneRouteModList.forEach((item) => { | 50 | cloneRouteModList.forEach((item) => { |
51 | - const { layout, routes, children } = item as RouteModule; | ||
52 | - if (layout) { | ||
53 | - layout.children = routes || children; | ||
54 | - routeList.push(layout); | 51 | + if (item.meta?.single) { |
52 | + const realItem = item?.children?.[0]; | ||
53 | + realItem && routeList.push(realItem); | ||
55 | } else { | 54 | } else { |
56 | - routes && routeList.push(...routes); | 55 | + routeList.push(item); |
57 | } | 56 | } |
58 | }); | 57 | }); |
59 | return treeMap(routeList, { | 58 | return treeMap(routeList, { |
src/router/helper/routeHelper.ts
0 → 100644
1 | +import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types'; | ||
2 | +import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'; | ||
3 | + | ||
4 | +import { appStore } from '/@/store/modules/app'; | ||
5 | +import { tabStore } from '/@/store/modules/tab'; | ||
6 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; | ||
7 | +import dynamicImport from './dynamicImport'; | ||
8 | +import { cloneDeep } from 'lodash-es'; | ||
9 | + | ||
10 | +// 动态引入 | ||
11 | +function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { | ||
12 | + if (!routes) return; | ||
13 | + routes.forEach((item) => { | ||
14 | + const { component, name } = item; | ||
15 | + const { children } = item; | ||
16 | + if (component) { | ||
17 | + item.component = dynamicImport(component); | ||
18 | + } else if (name) { | ||
19 | + item.component = getParentLayout(name); | ||
20 | + } | ||
21 | + children && asyncImportRoute(children); | ||
22 | + }); | ||
23 | +} | ||
24 | + | ||
25 | +function getLayoutComp(comp: string) { | ||
26 | + return comp === 'LAYOUT' ? LAYOUT : ''; | ||
27 | +} | ||
28 | + | ||
29 | +// Turn background objects into routing objects | ||
30 | +export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] { | ||
31 | + routeList.forEach((route) => { | ||
32 | + if (route.component) { | ||
33 | + if ((route.component as string).toUpperCase() === 'LAYOUT') { | ||
34 | + route.component = getLayoutComp(route.component); | ||
35 | + } else { | ||
36 | + route.children = [cloneDeep(route)]; | ||
37 | + route.component = LAYOUT; | ||
38 | + route.name = `${route.name}Parent`; | ||
39 | + route.path = ''; | ||
40 | + const meta = route.meta || {}; | ||
41 | + meta.single = true; | ||
42 | + meta.affix = false; | ||
43 | + route.meta = meta; | ||
44 | + } | ||
45 | + } | ||
46 | + route.children && asyncImportRoute(route.children); | ||
47 | + }); | ||
48 | + return (routeList as unknown) as T[]; | ||
49 | +} | ||
50 | + | ||
51 | +/** | ||
52 | + * Determine whether the tab has been opened | ||
53 | + * @param toPath | ||
54 | + */ | ||
55 | +export function getIsOpenTab(toPath: string) { | ||
56 | + const { openKeepAlive, multiTabsSetting: { show } = {} } = appStore.getProjectConfig; | ||
57 | + | ||
58 | + if (show && openKeepAlive) { | ||
59 | + const tabList = tabStore.getTabsState; | ||
60 | + return tabList.some((tab) => tab.path === toPath); | ||
61 | + } | ||
62 | + return false; | ||
63 | +} | ||
64 | + | ||
65 | +export function getParams(data: any = {}) { | ||
66 | + const { params = {} } = data; | ||
67 | + let ret = ''; | ||
68 | + Object.keys(params).forEach((key) => { | ||
69 | + const p = params[key]; | ||
70 | + ret += `/${p}`; | ||
71 | + }); | ||
72 | + return ret; | ||
73 | +} | ||
74 | + | ||
75 | +// Return to the new routing structure, not affected by the original example | ||
76 | +export function getRoute(route: RouteLocationNormalized): RouteLocationNormalized { | ||
77 | + if (!route) return route; | ||
78 | + const { matched, ...opt } = route; | ||
79 | + return { | ||
80 | + ...opt, | ||
81 | + matched: (matched | ||
82 | + ? matched.map((item) => ({ | ||
83 | + meta: item.meta, | ||
84 | + name: item.name, | ||
85 | + path: item.path, | ||
86 | + })) | ||
87 | + : undefined) as RouteRecordNormalized[], | ||
88 | + }; | ||
89 | +} |
src/router/menus/index.ts
@@ -2,7 +2,7 @@ import type { Menu, MenuModule } from '/@/router/types'; | @@ -2,7 +2,7 @@ import type { Menu, MenuModule } from '/@/router/types'; | ||
2 | import type { RouteRecordNormalized } from 'vue-router'; | 2 | import type { RouteRecordNormalized } from 'vue-router'; |
3 | import { appStore } from '/@/store/modules/app'; | 3 | import { appStore } from '/@/store/modules/app'; |
4 | import { permissionStore } from '/@/store/modules/permission'; | 4 | import { permissionStore } from '/@/store/modules/permission'; |
5 | -import { transformMenuModule, flatMenus, getAllParentPath } from '/@/utils/helper/menuHelper'; | 5 | +import { transformMenuModule, flatMenus, getAllParentPath } from '/@/router/helper/menuHelper'; |
6 | import { filter } from '/@/utils/helper/treeHelper'; | 6 | import { filter } from '/@/utils/helper/treeHelper'; |
7 | import router from '/@/router'; | 7 | import router from '/@/router'; |
8 | import { PermissionModeEnum } from '/@/enums/appEnum'; | 8 | import { PermissionModeEnum } from '/@/enums/appEnum'; |
src/router/menus/modules/dashboard.ts
1 | import type { MenuModule } from '/@/router/types.d'; | 1 | import type { MenuModule } from '/@/router/types.d'; |
2 | 2 | ||
3 | -const menu: MenuModule[] = [ | ||
4 | - { | ||
5 | - orderNo: 0, | ||
6 | - menu: { | ||
7 | - path: '/dashboard/welcome', | ||
8 | - name: 'routes.dashboard.welcome', | ||
9 | - }, | 3 | +const menu: MenuModule = { |
4 | + orderNo: 10, | ||
5 | + menu: { | ||
6 | + name: 'routes.dashboard.dashboard', | ||
7 | + path: '/dashboard', | ||
8 | + children: [ | ||
9 | + { | ||
10 | + path: '/workbench', | ||
11 | + name: 'routes.dashboard.workbench', | ||
12 | + }, | ||
13 | + { | ||
14 | + path: '/analysis', | ||
15 | + name: 'routes.dashboard.analysis', | ||
16 | + }, | ||
17 | + ], | ||
10 | }, | 18 | }, |
11 | - { | ||
12 | - orderNo: 10, | ||
13 | - menu: { | ||
14 | - name: 'routes.dashboard.dashboard', | ||
15 | - path: '/dashboard', | ||
16 | - children: [ | ||
17 | - { | ||
18 | - path: '/workbench', | ||
19 | - name: 'routes.dashboard.workbench', | ||
20 | - }, | ||
21 | - { | ||
22 | - path: '/analysis', | ||
23 | - name: 'routes.dashboard.analysis', | ||
24 | - }, | ||
25 | - // { | ||
26 | - // path: '/welcome', | ||
27 | - // name: 'routes.dashboard.welcome', | ||
28 | - // }, | ||
29 | - ], | ||
30 | - }, | ||
31 | - }, | ||
32 | -]; | 19 | +}; |
33 | export default menu; | 20 | export default menu; |
src/router/menus/modules/demo/level.ts
0 → 100644
1 | +import type { MenuModule } from '/@/router/types.d'; | ||
2 | + | ||
3 | +const menu: MenuModule = { | ||
4 | + orderNo: 2000, | ||
5 | + menu: { | ||
6 | + name: 'routes.demo.level.level', | ||
7 | + path: '/level', | ||
8 | + tag: { | ||
9 | + dot: true, | ||
10 | + }, | ||
11 | + children: [ | ||
12 | + { | ||
13 | + path: 'menu1', | ||
14 | + name: 'Menu1', | ||
15 | + children: [ | ||
16 | + { | ||
17 | + path: 'menu1-1', | ||
18 | + name: 'Menu1-1', | ||
19 | + children: [ | ||
20 | + { | ||
21 | + path: 'menu1-1-1', | ||
22 | + name: 'Menu1-1-1', | ||
23 | + }, | ||
24 | + ], | ||
25 | + }, | ||
26 | + { | ||
27 | + path: 'menu1-2', | ||
28 | + name: 'Menu1-2', | ||
29 | + }, | ||
30 | + ], | ||
31 | + }, | ||
32 | + { | ||
33 | + path: 'menu2', | ||
34 | + name: 'Menu2', | ||
35 | + }, | ||
36 | + ], | ||
37 | + }, | ||
38 | +}; | ||
39 | +export default menu; |
src/router/menus/modules/home.ts
0 → 100644
src/router/routes/index.ts
1 | import type { AppRouteRecordRaw, AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteRecordRaw, AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { DEFAULT_LAYOUT_COMPONENT, PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '../constant'; | ||
4 | -import { genRouteModule } from '/@/utils/helper/routeHelper'; | 3 | +import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE, LAYOUT } from '../constant'; |
4 | +import { PageEnum } from '/@/enums/pageEnum'; | ||
5 | + | ||
5 | import modules from 'globby!/@/router/routes/modules/**/*.@(ts)'; | 6 | import modules from 'globby!/@/router/routes/modules/**/*.@(ts)'; |
6 | 7 | ||
7 | const routeModuleList: AppRouteModule[] = []; | 8 | const routeModuleList: AppRouteModule[] = []; |
8 | 9 | ||
9 | Object.keys(modules).forEach((key) => { | 10 | Object.keys(modules).forEach((key) => { |
10 | - routeModuleList.push(modules[key]); | 11 | + const mod = Array.isArray(modules[key]) ? [...modules[key]] : [modules[key]]; |
12 | + routeModuleList.push(...mod); | ||
11 | }); | 13 | }); |
12 | 14 | ||
13 | -export const asyncRoutes = [ | ||
14 | - REDIRECT_ROUTE, | ||
15 | - PAGE_NOT_FOUND_ROUTE, | ||
16 | - ...genRouteModule(routeModuleList), | ||
17 | -]; | 15 | +export const asyncRoutes = [PAGE_NOT_FOUND_ROUTE, ...routeModuleList]; |
18 | 16 | ||
19 | -// 主框架根路由 | ||
20 | -export const RootRoute: AppRouteRecordRaw = { | 17 | +const MainRoute: AppRouteModule = { |
21 | path: '/', | 18 | path: '/', |
22 | - name: 'Root', | ||
23 | - component: DEFAULT_LAYOUT_COMPONENT, | ||
24 | - redirect: '/dashboard', | 19 | + name: 'MainRoute', |
20 | + component: LAYOUT, | ||
21 | + redirect: PageEnum.BASE_HOME, | ||
25 | meta: { | 22 | meta: { |
26 | - title: 'Root', | 23 | + icon: 'ant-design:home-outlined', |
24 | + title: 'routes.dashboard.dashboard', | ||
27 | }, | 25 | }, |
28 | - children: [], | ||
29 | }; | 26 | }; |
30 | 27 | ||
31 | export const LoginRoute: AppRouteRecordRaw = { | 28 | export const LoginRoute: AppRouteRecordRaw = { |
@@ -38,4 +35,4 @@ export const LoginRoute: AppRouteRecordRaw = { | @@ -38,4 +35,4 @@ export const LoginRoute: AppRouteRecordRaw = { | ||
38 | }; | 35 | }; |
39 | 36 | ||
40 | // 基础路由 不用权限 | 37 | // 基础路由 不用权限 |
41 | -export const basicRoutes = [LoginRoute, RootRoute]; | 38 | +export const basicRoutes = [LoginRoute, MainRoute, REDIRECT_ROUTE]; |
src/router/routes/modules/dashboard.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const dashboard: AppRouteModule = { | 5 | const dashboard: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/dashboard', | ||
8 | - name: 'Dashboard', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/dashboard/welcome', | ||
11 | - meta: { | ||
12 | - icon: 'ant-design:home-outlined', | ||
13 | - title: 'routes.dashboard.dashboard', | ||
14 | - }, | 6 | + path: '/dashboard', |
7 | + name: 'Dashboard', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/dashboard/welcome', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:home-outlined', | ||
12 | + title: 'routes.dashboard.dashboard', | ||
15 | }, | 13 | }, |
16 | - | ||
17 | - routes: [ | ||
18 | - { | ||
19 | - path: '/welcome', | ||
20 | - name: 'Welcome', | ||
21 | - component: () => import('/@/views/dashboard/welcome/index.vue'), | ||
22 | - meta: { | ||
23 | - title: 'routes.dashboard.welcome', | ||
24 | - affix: true, | ||
25 | - icon: 'ant-design:home-outlined', | ||
26 | - }, | ||
27 | - }, | 14 | + children: [ |
28 | { | 15 | { |
29 | - path: '/workbench', | 16 | + path: 'workbench', |
30 | name: 'Workbench', | 17 | name: 'Workbench', |
31 | component: () => import('/@/views/dashboard/workbench/index.vue'), | 18 | component: () => import('/@/views/dashboard/workbench/index.vue'), |
32 | meta: { | 19 | meta: { |
@@ -34,7 +21,7 @@ const dashboard: AppRouteModule = { | @@ -34,7 +21,7 @@ const dashboard: AppRouteModule = { | ||
34 | }, | 21 | }, |
35 | }, | 22 | }, |
36 | { | 23 | { |
37 | - path: '/analysis', | 24 | + path: 'analysis', |
38 | name: 'Analysis', | 25 | name: 'Analysis', |
39 | component: () => import('/@/views/dashboard/analysis/index.vue'), | 26 | component: () => import('/@/views/dashboard/analysis/index.vue'), |
40 | meta: { | 27 | meta: { |
src/router/routes/modules/demo/charts.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const charts: AppRouteModule = { | 5 | const charts: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/charts', | ||
8 | - name: 'Charts', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/charts/apexChart', | ||
11 | - meta: { | ||
12 | - icon: 'ant-design:area-chart-outlined', | ||
13 | - title: 'routes.demo.charts.charts', | ||
14 | - }, | 6 | + path: '/charts', |
7 | + name: 'Charts', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/charts/apexChart', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:area-chart-outlined', | ||
12 | + title: 'routes.demo.charts.charts', | ||
15 | }, | 13 | }, |
16 | - | ||
17 | - routes: [ | 14 | + children: [ |
18 | { | 15 | { |
19 | - path: '/echarts', | 16 | + path: 'echarts', |
20 | name: 'Echarts', | 17 | name: 'Echarts', |
18 | + component: getParentLayout('Echarts'), | ||
21 | meta: { | 19 | meta: { |
22 | title: 'Echarts', | 20 | title: 'Echarts', |
23 | }, | 21 | }, |
@@ -49,7 +47,7 @@ const charts: AppRouteModule = { | @@ -49,7 +47,7 @@ const charts: AppRouteModule = { | ||
49 | ], | 47 | ], |
50 | }, | 48 | }, |
51 | { | 49 | { |
52 | - path: '/apexChart', | 50 | + path: 'apexChart', |
53 | name: 'ApexChart', | 51 | name: 'ApexChart', |
54 | meta: { | 52 | meta: { |
55 | title: 'routes.demo.charts.apexChart', | 53 | title: 'routes.demo.charts.apexChart', |
src/router/routes/modules/demo/comp.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const comp: AppRouteModule = { | 5 | const comp: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/comp', | ||
8 | - name: 'Comp', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/comp/basic', | ||
11 | - meta: { | ||
12 | - icon: 'ant-design:table-outlined', | ||
13 | - title: 'routes.demo.comp.comp', | ||
14 | - }, | 6 | + path: '/comp', |
7 | + name: 'Comp', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/comp/basic', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:table-outlined', | ||
12 | + title: 'routes.demo.comp.comp', | ||
15 | }, | 13 | }, |
16 | 14 | ||
17 | - routes: [ | 15 | + children: [ |
18 | { | 16 | { |
19 | - path: '/basic', | 17 | + path: 'basic', |
20 | name: 'BasicDemo', | 18 | name: 'BasicDemo', |
21 | component: () => import('/@/views/demo/comp/button/index.vue'), | 19 | component: () => import('/@/views/demo/comp/button/index.vue'), |
22 | meta: { | 20 | meta: { |
@@ -24,7 +22,7 @@ const comp: AppRouteModule = { | @@ -24,7 +22,7 @@ const comp: AppRouteModule = { | ||
24 | }, | 22 | }, |
25 | }, | 23 | }, |
26 | { | 24 | { |
27 | - path: '/transition', | 25 | + path: 'transition', |
28 | name: 'transitionDemo', | 26 | name: 'transitionDemo', |
29 | component: () => import('/@/views/demo/comp/transition/index.vue'), | 27 | component: () => import('/@/views/demo/comp/transition/index.vue'), |
30 | meta: { | 28 | meta: { |
@@ -32,7 +30,7 @@ const comp: AppRouteModule = { | @@ -32,7 +30,7 @@ const comp: AppRouteModule = { | ||
32 | }, | 30 | }, |
33 | }, | 31 | }, |
34 | { | 32 | { |
35 | - path: '/countTo', | 33 | + path: 'countTo', |
36 | name: 'CountTo', | 34 | name: 'CountTo', |
37 | component: () => import('/@/views/demo/comp/count-to/index.vue'), | 35 | component: () => import('/@/views/demo/comp/count-to/index.vue'), |
38 | meta: { | 36 | meta: { |
@@ -41,9 +39,10 @@ const comp: AppRouteModule = { | @@ -41,9 +39,10 @@ const comp: AppRouteModule = { | ||
41 | }, | 39 | }, |
42 | 40 | ||
43 | { | 41 | { |
44 | - path: '/scroll', | 42 | + path: 'scroll', |
45 | name: 'ScrollDemo', | 43 | name: 'ScrollDemo', |
46 | redirect: '/comp/scroll/basic', | 44 | redirect: '/comp/scroll/basic', |
45 | + component: getParentLayout('ScrollDemo'), | ||
47 | meta: { | 46 | meta: { |
48 | title: 'routes.demo.comp.scroll', | 47 | title: 'routes.demo.comp.scroll', |
49 | }, | 48 | }, |
@@ -76,7 +75,7 @@ const comp: AppRouteModule = { | @@ -76,7 +75,7 @@ const comp: AppRouteModule = { | ||
76 | }, | 75 | }, |
77 | 76 | ||
78 | { | 77 | { |
79 | - path: '/modal', | 78 | + path: 'modal', |
80 | name: 'ModalDemo', | 79 | name: 'ModalDemo', |
81 | component: () => import('/@/views/demo/comp/modal/index.vue'), | 80 | component: () => import('/@/views/demo/comp/modal/index.vue'), |
82 | meta: { | 81 | meta: { |
@@ -84,7 +83,7 @@ const comp: AppRouteModule = { | @@ -84,7 +83,7 @@ const comp: AppRouteModule = { | ||
84 | }, | 83 | }, |
85 | }, | 84 | }, |
86 | { | 85 | { |
87 | - path: '/drawer', | 86 | + path: 'drawer', |
88 | name: 'DrawerDemo', | 87 | name: 'DrawerDemo', |
89 | component: () => import('/@/views/demo/comp/drawer/index.vue'), | 88 | component: () => import('/@/views/demo/comp/drawer/index.vue'), |
90 | meta: { | 89 | meta: { |
@@ -92,7 +91,7 @@ const comp: AppRouteModule = { | @@ -92,7 +91,7 @@ const comp: AppRouteModule = { | ||
92 | }, | 91 | }, |
93 | }, | 92 | }, |
94 | { | 93 | { |
95 | - path: '/desc', | 94 | + path: 'desc', |
96 | name: 'DescDemo', | 95 | name: 'DescDemo', |
97 | component: () => import('/@/views/demo/comp/desc/index.vue'), | 96 | component: () => import('/@/views/demo/comp/desc/index.vue'), |
98 | meta: { | 97 | meta: { |
@@ -101,8 +100,9 @@ const comp: AppRouteModule = { | @@ -101,8 +100,9 @@ const comp: AppRouteModule = { | ||
101 | }, | 100 | }, |
102 | 101 | ||
103 | { | 102 | { |
104 | - path: '/lazy', | ||
105 | - name: 'lazyDemo', | 103 | + path: 'lazy', |
104 | + name: 'LazyDemo', | ||
105 | + component: getParentLayout('LazyDemo'), | ||
106 | redirect: '/comp/lazy/basic', | 106 | redirect: '/comp/lazy/basic', |
107 | meta: { | 107 | meta: { |
108 | title: 'routes.demo.comp.lazy', | 108 | title: 'routes.demo.comp.lazy', |
@@ -127,8 +127,9 @@ const comp: AppRouteModule = { | @@ -127,8 +127,9 @@ const comp: AppRouteModule = { | ||
127 | ], | 127 | ], |
128 | }, | 128 | }, |
129 | { | 129 | { |
130 | - path: '/verify', | 130 | + path: 'verify', |
131 | name: 'VerifyDemo', | 131 | name: 'VerifyDemo', |
132 | + component: getParentLayout('VerifyDemo'), | ||
132 | redirect: '/comp/verify/drag', | 133 | redirect: '/comp/verify/drag', |
133 | meta: { | 134 | meta: { |
134 | title: 'routes.demo.comp.verify', | 135 | title: 'routes.demo.comp.verify', |
@@ -155,7 +156,7 @@ const comp: AppRouteModule = { | @@ -155,7 +156,7 @@ const comp: AppRouteModule = { | ||
155 | // | 156 | // |
156 | 157 | ||
157 | { | 158 | { |
158 | - path: '/qrcode', | 159 | + path: 'qrcode', |
159 | name: 'QrCodeDemo', | 160 | name: 'QrCodeDemo', |
160 | component: () => import('/@/views/demo/comp/qrcode/index.vue'), | 161 | component: () => import('/@/views/demo/comp/qrcode/index.vue'), |
161 | meta: { | 162 | meta: { |
@@ -163,7 +164,7 @@ const comp: AppRouteModule = { | @@ -163,7 +164,7 @@ const comp: AppRouteModule = { | ||
163 | }, | 164 | }, |
164 | }, | 165 | }, |
165 | { | 166 | { |
166 | - path: '/strength-meter', | 167 | + path: 'strength-meter', |
167 | name: 'StrengthMeterDemo', | 168 | name: 'StrengthMeterDemo', |
168 | component: () => import('/@/views/demo/comp/strength-meter/index.vue'), | 169 | component: () => import('/@/views/demo/comp/strength-meter/index.vue'), |
169 | meta: { | 170 | meta: { |
@@ -171,7 +172,7 @@ const comp: AppRouteModule = { | @@ -171,7 +172,7 @@ const comp: AppRouteModule = { | ||
171 | }, | 172 | }, |
172 | }, | 173 | }, |
173 | { | 174 | { |
174 | - path: '/upload', | 175 | + path: 'upload', |
175 | name: 'UploadDemo', | 176 | name: 'UploadDemo', |
176 | component: () => import('/@/views/demo/comp/upload/index.vue'), | 177 | component: () => import('/@/views/demo/comp/upload/index.vue'), |
177 | meta: { | 178 | meta: { |
@@ -179,7 +180,7 @@ const comp: AppRouteModule = { | @@ -179,7 +180,7 @@ const comp: AppRouteModule = { | ||
179 | }, | 180 | }, |
180 | }, | 181 | }, |
181 | { | 182 | { |
182 | - path: '/loading', | 183 | + path: 'loading', |
183 | name: 'LoadingDemo', | 184 | name: 'LoadingDemo', |
184 | component: () => import('/@/views/demo/comp/loading/index.vue'), | 185 | component: () => import('/@/views/demo/comp/loading/index.vue'), |
185 | meta: { | 186 | meta: { |
src/router/routes/modules/demo/editor.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const editor: AppRouteModule = { | 5 | const editor: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/editor', | ||
8 | - name: 'Editor', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/editor/markdown', | ||
11 | - meta: { | ||
12 | - icon: 'ant-design:table-outlined', | ||
13 | - title: 'routes.demo.editor.editor', | ||
14 | - }, | 6 | + path: '/editor', |
7 | + name: 'Editor', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/editor/markdown', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:table-outlined', | ||
12 | + title: 'routes.demo.editor.editor', | ||
15 | }, | 13 | }, |
16 | - | ||
17 | - routes: [ | 14 | + children: [ |
18 | { | 15 | { |
19 | - path: '/markdown', | 16 | + path: 'markdown', |
20 | name: 'MarkdownDemo', | 17 | name: 'MarkdownDemo', |
21 | component: () => import('/@/views/demo/editor/Markdown.vue'), | 18 | component: () => import('/@/views/demo/editor/Markdown.vue'), |
22 | meta: { | 19 | meta: { |
@@ -24,7 +21,8 @@ const editor: AppRouteModule = { | @@ -24,7 +21,8 @@ const editor: AppRouteModule = { | ||
24 | }, | 21 | }, |
25 | }, | 22 | }, |
26 | { | 23 | { |
27 | - path: '/tinymce', | 24 | + path: 'tinymce', |
25 | + component: getParentLayout('TinymceDemo'), | ||
28 | name: 'TinymceDemo', | 26 | name: 'TinymceDemo', |
29 | meta: { | 27 | meta: { |
30 | title: 'routes.demo.editor.tinymce', | 28 | title: 'routes.demo.editor.tinymce', |
@@ -39,7 +37,6 @@ const editor: AppRouteModule = { | @@ -39,7 +37,6 @@ const editor: AppRouteModule = { | ||
39 | title: 'routes.demo.editor.tinymceBasic', | 37 | title: 'routes.demo.editor.tinymceBasic', |
40 | }, | 38 | }, |
41 | }, | 39 | }, |
42 | - // TODO | ||
43 | { | 40 | { |
44 | path: 'editor', | 41 | path: 'editor', |
45 | name: 'TinymceFormDemo', | 42 | name: 'TinymceFormDemo', |
src/router/routes/modules/demo/excel.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const excel: AppRouteModule = { | 5 | const excel: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/excel', | ||
8 | - name: 'Excel', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/excel/customExport', | ||
11 | - meta: { | ||
12 | - icon: 'mdi:microsoft-excel', | ||
13 | - title: 'routes.demo.excel.excel', | ||
14 | - }, | 6 | + path: '/excel', |
7 | + name: 'Excel', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/excel/customExport', | ||
10 | + meta: { | ||
11 | + icon: 'mdi:microsoft-excel', | ||
12 | + title: 'routes.demo.excel.excel', | ||
15 | }, | 13 | }, |
16 | 14 | ||
17 | - routes: [ | 15 | + children: [ |
18 | { | 16 | { |
19 | - path: '/customExport', | 17 | + path: 'customExport', |
20 | name: 'CustomExport', | 18 | name: 'CustomExport', |
21 | component: () => import('/@/views/demo/excel/CustomExport.vue'), | 19 | component: () => import('/@/views/demo/excel/CustomExport.vue'), |
22 | meta: { | 20 | meta: { |
@@ -24,7 +22,7 @@ const excel: AppRouteModule = { | @@ -24,7 +22,7 @@ const excel: AppRouteModule = { | ||
24 | }, | 22 | }, |
25 | }, | 23 | }, |
26 | { | 24 | { |
27 | - path: '/jsonExport', | 25 | + path: 'jsonExport', |
28 | name: 'JsonExport', | 26 | name: 'JsonExport', |
29 | component: () => import('/@/views/demo/excel/JsonExport.vue'), | 27 | component: () => import('/@/views/demo/excel/JsonExport.vue'), |
30 | meta: { | 28 | meta: { |
@@ -32,7 +30,7 @@ const excel: AppRouteModule = { | @@ -32,7 +30,7 @@ const excel: AppRouteModule = { | ||
32 | }, | 30 | }, |
33 | }, | 31 | }, |
34 | { | 32 | { |
35 | - path: '/arrayExport', | 33 | + path: 'arrayExport', |
36 | name: 'ArrayExport', | 34 | name: 'ArrayExport', |
37 | component: () => import('/@/views/demo/excel/ArrayExport.vue'), | 35 | component: () => import('/@/views/demo/excel/ArrayExport.vue'), |
38 | meta: { | 36 | meta: { |
@@ -40,7 +38,7 @@ const excel: AppRouteModule = { | @@ -40,7 +38,7 @@ const excel: AppRouteModule = { | ||
40 | }, | 38 | }, |
41 | }, | 39 | }, |
42 | { | 40 | { |
43 | - path: '/importExcel', | 41 | + path: 'importExcel', |
44 | name: 'ImportExcel', | 42 | name: 'ImportExcel', |
45 | component: () => import('/@/views/demo/excel/ImportExcel.vue'), | 43 | component: () => import('/@/views/demo/excel/ImportExcel.vue'), |
46 | meta: { | 44 | meta: { |
src/router/routes/modules/demo/feat.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const feat: AppRouteModule = { | 5 | const feat: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/feat', | ||
8 | - name: 'FeatDemo', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/feat/icon', | ||
11 | - meta: { | ||
12 | - icon: 'ic:outline-featured-play-list', | ||
13 | - title: 'routes.demo.feat.feat', | ||
14 | - }, | 6 | + path: '/feat', |
7 | + name: 'FeatDemo', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/feat/icon', | ||
10 | + meta: { | ||
11 | + icon: 'ic:outline-featured-play-list', | ||
12 | + title: 'routes.demo.feat.feat', | ||
15 | }, | 13 | }, |
16 | - | ||
17 | - routes: [ | 14 | + children: [ |
18 | { | 15 | { |
19 | - path: '/icon', | 16 | + path: 'icon', |
20 | name: 'IconDemo', | 17 | name: 'IconDemo', |
21 | component: () => import('/@/views/demo/feat/icon/index.vue'), | 18 | component: () => import('/@/views/demo/feat/icon/index.vue'), |
22 | meta: { | 19 | meta: { |
@@ -24,7 +21,7 @@ const feat: AppRouteModule = { | @@ -24,7 +21,7 @@ const feat: AppRouteModule = { | ||
24 | }, | 21 | }, |
25 | }, | 22 | }, |
26 | { | 23 | { |
27 | - path: '/tabs', | 24 | + path: 'tabs', |
28 | name: 'TabsDemo', | 25 | name: 'TabsDemo', |
29 | component: () => import('/@/views/demo/feat/tabs/index.vue'), | 26 | component: () => import('/@/views/demo/feat/tabs/index.vue'), |
30 | meta: { | 27 | meta: { |
@@ -33,7 +30,7 @@ const feat: AppRouteModule = { | @@ -33,7 +30,7 @@ const feat: AppRouteModule = { | ||
33 | }, | 30 | }, |
34 | 31 | ||
35 | { | 32 | { |
36 | - path: '/context-menu', | 33 | + path: 'context-menu', |
37 | name: 'ContextMenuDemo', | 34 | name: 'ContextMenuDemo', |
38 | component: () => import('/@/views/demo/feat/context-menu/index.vue'), | 35 | component: () => import('/@/views/demo/feat/context-menu/index.vue'), |
39 | meta: { | 36 | meta: { |
@@ -41,7 +38,7 @@ const feat: AppRouteModule = { | @@ -41,7 +38,7 @@ const feat: AppRouteModule = { | ||
41 | }, | 38 | }, |
42 | }, | 39 | }, |
43 | { | 40 | { |
44 | - path: '/download', | 41 | + path: 'download', |
45 | name: 'DownLoadDemo', | 42 | name: 'DownLoadDemo', |
46 | component: () => import('/@/views/demo/feat/download/index.vue'), | 43 | component: () => import('/@/views/demo/feat/download/index.vue'), |
47 | meta: { | 44 | meta: { |
@@ -49,7 +46,7 @@ const feat: AppRouteModule = { | @@ -49,7 +46,7 @@ const feat: AppRouteModule = { | ||
49 | }, | 46 | }, |
50 | }, | 47 | }, |
51 | { | 48 | { |
52 | - path: '/click-out-side', | 49 | + path: 'click-out-side', |
53 | name: 'ClickOutSideDemo', | 50 | name: 'ClickOutSideDemo', |
54 | component: () => import('/@/views/demo/feat/click-out-side/index.vue'), | 51 | component: () => import('/@/views/demo/feat/click-out-side/index.vue'), |
55 | meta: { | 52 | meta: { |
@@ -57,7 +54,7 @@ const feat: AppRouteModule = { | @@ -57,7 +54,7 @@ const feat: AppRouteModule = { | ||
57 | }, | 54 | }, |
58 | }, | 55 | }, |
59 | { | 56 | { |
60 | - path: '/img-preview', | 57 | + path: 'img-preview', |
61 | name: 'ImgPreview', | 58 | name: 'ImgPreview', |
62 | component: () => import('/@/views/demo/feat/img-preview/index.vue'), | 59 | component: () => import('/@/views/demo/feat/img-preview/index.vue'), |
63 | meta: { | 60 | meta: { |
@@ -65,7 +62,7 @@ const feat: AppRouteModule = { | @@ -65,7 +62,7 @@ const feat: AppRouteModule = { | ||
65 | }, | 62 | }, |
66 | }, | 63 | }, |
67 | { | 64 | { |
68 | - path: '/copy', | 65 | + path: 'copy', |
69 | name: 'CopyDemo', | 66 | name: 'CopyDemo', |
70 | component: () => import('/@/views/demo/feat/copy/index.vue'), | 67 | component: () => import('/@/views/demo/feat/copy/index.vue'), |
71 | meta: { | 68 | meta: { |
@@ -73,7 +70,7 @@ const feat: AppRouteModule = { | @@ -73,7 +70,7 @@ const feat: AppRouteModule = { | ||
73 | }, | 70 | }, |
74 | }, | 71 | }, |
75 | { | 72 | { |
76 | - path: '/msg', | 73 | + path: 'msg', |
77 | name: 'MsgDemo', | 74 | name: 'MsgDemo', |
78 | component: () => import('/@/views/demo/feat/msg/index.vue'), | 75 | component: () => import('/@/views/demo/feat/msg/index.vue'), |
79 | meta: { | 76 | meta: { |
@@ -81,7 +78,7 @@ const feat: AppRouteModule = { | @@ -81,7 +78,7 @@ const feat: AppRouteModule = { | ||
81 | }, | 78 | }, |
82 | }, | 79 | }, |
83 | { | 80 | { |
84 | - path: '/watermark', | 81 | + path: 'watermark', |
85 | name: 'WatermarkDemo', | 82 | name: 'WatermarkDemo', |
86 | component: () => import('/@/views/demo/feat/watermark/index.vue'), | 83 | component: () => import('/@/views/demo/feat/watermark/index.vue'), |
87 | meta: { | 84 | meta: { |
@@ -89,7 +86,7 @@ const feat: AppRouteModule = { | @@ -89,7 +86,7 @@ const feat: AppRouteModule = { | ||
89 | }, | 86 | }, |
90 | }, | 87 | }, |
91 | { | 88 | { |
92 | - path: '/full-screen', | 89 | + path: 'full-screen', |
93 | name: 'FullScreenDemo', | 90 | name: 'FullScreenDemo', |
94 | component: () => import('/@/views/demo/feat/full-screen/index.vue'), | 91 | component: () => import('/@/views/demo/feat/full-screen/index.vue'), |
95 | meta: { | 92 | meta: { |
@@ -97,7 +94,7 @@ const feat: AppRouteModule = { | @@ -97,7 +94,7 @@ const feat: AppRouteModule = { | ||
97 | }, | 94 | }, |
98 | }, | 95 | }, |
99 | { | 96 | { |
100 | - path: '/error-log', | 97 | + path: 'error-log', |
101 | name: 'ErrorLog', | 98 | name: 'ErrorLog', |
102 | component: () => import('/@/views/sys/error-log/index.vue'), | 99 | component: () => import('/@/views/sys/error-log/index.vue'), |
103 | meta: { | 100 | meta: { |
@@ -105,7 +102,7 @@ const feat: AppRouteModule = { | @@ -105,7 +102,7 @@ const feat: AppRouteModule = { | ||
105 | }, | 102 | }, |
106 | }, | 103 | }, |
107 | { | 104 | { |
108 | - path: '/testTab/:id', | 105 | + path: 'testTab/:id', |
109 | name: 'TestTab', | 106 | name: 'TestTab', |
110 | component: () => import('/@/views/demo/feat/tab-params/index.vue'), | 107 | component: () => import('/@/views/demo/feat/tab-params/index.vue'), |
111 | meta: { | 108 | meta: { |
src/router/routes/modules/demo/form.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const form: AppRouteModule = { | 5 | const form: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/form', | ||
8 | - name: 'FormDemo', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/form/basic', | ||
11 | - meta: { | ||
12 | - icon: 'ant-design:table-outlined', | ||
13 | - title: 'routes.demo.form.form', | ||
14 | - }, | 6 | + path: '/form', |
7 | + name: 'FormDemo', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/form/basic', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:table-outlined', | ||
12 | + title: 'routes.demo.form.form', | ||
15 | }, | 13 | }, |
16 | - | ||
17 | - routes: [ | 14 | + children: [ |
18 | { | 15 | { |
19 | - path: '/basic', | 16 | + path: 'basic', |
20 | name: 'FormBasicDemo', | 17 | name: 'FormBasicDemo', |
21 | component: () => import('/@/views/demo/form/index.vue'), | 18 | component: () => import('/@/views/demo/form/index.vue'), |
22 | meta: { | 19 | meta: { |
@@ -24,7 +21,7 @@ const form: AppRouteModule = { | @@ -24,7 +21,7 @@ const form: AppRouteModule = { | ||
24 | }, | 21 | }, |
25 | }, | 22 | }, |
26 | { | 23 | { |
27 | - path: '/useForm', | 24 | + path: 'useForm', |
28 | name: 'UseFormDemo', | 25 | name: 'UseFormDemo', |
29 | component: () => import('/@/views/demo/form/UseForm.vue'), | 26 | component: () => import('/@/views/demo/form/UseForm.vue'), |
30 | meta: { | 27 | meta: { |
@@ -32,7 +29,7 @@ const form: AppRouteModule = { | @@ -32,7 +29,7 @@ const form: AppRouteModule = { | ||
32 | }, | 29 | }, |
33 | }, | 30 | }, |
34 | { | 31 | { |
35 | - path: '/refForm', | 32 | + path: 'refForm', |
36 | name: 'RefFormDemo', | 33 | name: 'RefFormDemo', |
37 | component: () => import('/@/views/demo/form/RefForm.vue'), | 34 | component: () => import('/@/views/demo/form/RefForm.vue'), |
38 | meta: { | 35 | meta: { |
@@ -40,7 +37,7 @@ const form: AppRouteModule = { | @@ -40,7 +37,7 @@ const form: AppRouteModule = { | ||
40 | }, | 37 | }, |
41 | }, | 38 | }, |
42 | { | 39 | { |
43 | - path: '/advancedForm', | 40 | + path: 'advancedForm', |
44 | name: 'AdvancedFormDemo', | 41 | name: 'AdvancedFormDemo', |
45 | component: () => import('/@/views/demo/form/AdvancedForm.vue'), | 42 | component: () => import('/@/views/demo/form/AdvancedForm.vue'), |
46 | meta: { | 43 | meta: { |
@@ -48,7 +45,7 @@ const form: AppRouteModule = { | @@ -48,7 +45,7 @@ const form: AppRouteModule = { | ||
48 | }, | 45 | }, |
49 | }, | 46 | }, |
50 | { | 47 | { |
51 | - path: '/ruleForm', | 48 | + path: 'ruleForm', |
52 | name: 'RuleFormDemo', | 49 | name: 'RuleFormDemo', |
53 | component: () => import('/@/views/demo/form/RuleForm.vue'), | 50 | component: () => import('/@/views/demo/form/RuleForm.vue'), |
54 | meta: { | 51 | meta: { |
@@ -56,7 +53,7 @@ const form: AppRouteModule = { | @@ -56,7 +53,7 @@ const form: AppRouteModule = { | ||
56 | }, | 53 | }, |
57 | }, | 54 | }, |
58 | { | 55 | { |
59 | - path: '/dynamicForm', | 56 | + path: 'dynamicForm', |
60 | name: 'DynamicFormDemo', | 57 | name: 'DynamicFormDemo', |
61 | component: () => import('/@/views/demo/form/DynamicForm.vue'), | 58 | component: () => import('/@/views/demo/form/DynamicForm.vue'), |
62 | meta: { | 59 | meta: { |
@@ -64,7 +61,7 @@ const form: AppRouteModule = { | @@ -64,7 +61,7 @@ const form: AppRouteModule = { | ||
64 | }, | 61 | }, |
65 | }, | 62 | }, |
66 | { | 63 | { |
67 | - path: '/customerForm', | 64 | + path: 'customerForm', |
68 | name: 'CustomerFormDemo', | 65 | name: 'CustomerFormDemo', |
69 | component: () => import('/@/views/demo/form/CustomerForm.vue'), | 66 | component: () => import('/@/views/demo/form/CustomerForm.vue'), |
70 | meta: { | 67 | meta: { |
src/router/routes/modules/demo/iframe.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | const IFrame = () => import('/@/views/sys/iframe/FrameBlank.vue'); | 4 | const IFrame = () => import('/@/views/sys/iframe/FrameBlank.vue'); |
5 | 5 | ||
6 | const iframe: AppRouteModule = { | 6 | const iframe: AppRouteModule = { |
7 | - layout: { | ||
8 | - path: '/frame', | ||
9 | - name: 'Frame', | ||
10 | - component: PAGE_LAYOUT_COMPONENT, | ||
11 | - redirect: '/frame/antv', | ||
12 | - meta: { | ||
13 | - icon: 'mdi:page-next-outline', | ||
14 | - title: 'routes.demo.iframe.frame', | ||
15 | - }, | 7 | + path: '/frame', |
8 | + name: 'Frame', | ||
9 | + component: LAYOUT, | ||
10 | + redirect: '/frame/antv', | ||
11 | + meta: { | ||
12 | + icon: 'mdi:page-next-outline', | ||
13 | + title: 'routes.demo.iframe.frame', | ||
16 | }, | 14 | }, |
17 | 15 | ||
18 | - routes: [ | 16 | + children: [ |
19 | { | 17 | { |
20 | - path: '/antv', | 18 | + path: 'antv', |
21 | name: 'Antv', | 19 | name: 'Antv', |
22 | component: IFrame, | 20 | component: IFrame, |
23 | meta: { | 21 | meta: { |
@@ -27,7 +25,7 @@ const iframe: AppRouteModule = { | @@ -27,7 +25,7 @@ const iframe: AppRouteModule = { | ||
27 | }, | 25 | }, |
28 | }, | 26 | }, |
29 | { | 27 | { |
30 | - path: '/doc', | 28 | + path: 'doc', |
31 | name: 'Doc', | 29 | name: 'Doc', |
32 | component: IFrame, | 30 | component: IFrame, |
33 | meta: { | 31 | meta: { |
@@ -37,7 +35,7 @@ const iframe: AppRouteModule = { | @@ -37,7 +35,7 @@ const iframe: AppRouteModule = { | ||
37 | }, | 35 | }, |
38 | }, | 36 | }, |
39 | { | 37 | { |
40 | - path: '/docExternal', | 38 | + path: 'docExternal', |
41 | name: 'DocExternal', | 39 | name: 'DocExternal', |
42 | component: IFrame, | 40 | component: IFrame, |
43 | meta: { | 41 | meta: { |
src/router/routes/modules/demo/level.ts
0 → 100644
1 | +import type { AppRouteModule } from '/@/router/types'; | ||
2 | + | ||
3 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; | ||
4 | + | ||
5 | +const permission: AppRouteModule = { | ||
6 | + path: '/level', | ||
7 | + name: 'Level', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/level/menu1/menu1-1', | ||
10 | + meta: { | ||
11 | + icon: 'carbon:user-role', | ||
12 | + title: 'routes.demo.level.level', | ||
13 | + }, | ||
14 | + | ||
15 | + children: [ | ||
16 | + { | ||
17 | + path: 'menu1', | ||
18 | + name: 'Menu1Demo', | ||
19 | + component: getParentLayout('Menu1Demo'), | ||
20 | + meta: { | ||
21 | + title: 'Menu1', | ||
22 | + }, | ||
23 | + children: [ | ||
24 | + { | ||
25 | + path: 'menu1-1', | ||
26 | + name: 'Menu11Demo', | ||
27 | + component: getParentLayout('Menu11Demo'), | ||
28 | + meta: { | ||
29 | + title: 'Menu1-1', | ||
30 | + }, | ||
31 | + children: [ | ||
32 | + { | ||
33 | + path: 'menu1-1-1', | ||
34 | + name: 'Menu111Demo', | ||
35 | + component: () => import('/@/views/demo/level/Menu111.vue'), | ||
36 | + meta: { | ||
37 | + title: 'Menu111', | ||
38 | + }, | ||
39 | + }, | ||
40 | + ], | ||
41 | + }, | ||
42 | + { | ||
43 | + path: 'menu1-2', | ||
44 | + name: 'Menu12Demo', | ||
45 | + component: () => import('/@/views/demo/level/Menu12.vue'), | ||
46 | + meta: { | ||
47 | + title: 'Menu1-2', | ||
48 | + }, | ||
49 | + }, | ||
50 | + ], | ||
51 | + }, | ||
52 | + { | ||
53 | + path: 'menu2', | ||
54 | + name: 'Menu2Demo', | ||
55 | + component: () => import('/@/views/demo/level/Menu2.vue'), | ||
56 | + meta: { | ||
57 | + title: 'Menu2', | ||
58 | + }, | ||
59 | + }, | ||
60 | + ], | ||
61 | +}; | ||
62 | + | ||
63 | +export default permission; |
src/router/routes/modules/demo/page.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; |
4 | import { ExceptionEnum } from '/@/enums/exceptionEnum'; | 4 | import { ExceptionEnum } from '/@/enums/exceptionEnum'; |
5 | 5 | ||
6 | const ExceptionPage = () => import('/@/views/sys/exception/Exception'); | 6 | const ExceptionPage = () => import('/@/views/sys/exception/Exception'); |
@@ -8,7 +8,7 @@ const ExceptionPage = () => import('/@/views/sys/exception/Exception'); | @@ -8,7 +8,7 @@ const ExceptionPage = () => import('/@/views/sys/exception/Exception'); | ||
8 | const page: AppRouteModule = { | 8 | const page: AppRouteModule = { |
9 | path: '/page-demo', | 9 | path: '/page-demo', |
10 | name: 'PageDemo', | 10 | name: 'PageDemo', |
11 | - component: PAGE_LAYOUT_COMPONENT, | 11 | + component: LAYOUT, |
12 | redirect: '/page-demo/exception', | 12 | redirect: '/page-demo/exception', |
13 | meta: { | 13 | meta: { |
14 | icon: 'mdi:page-next-outline', | 14 | icon: 'mdi:page-next-outline', |
@@ -17,9 +17,10 @@ const page: AppRouteModule = { | @@ -17,9 +17,10 @@ const page: AppRouteModule = { | ||
17 | children: [ | 17 | children: [ |
18 | // =============================form start============================= | 18 | // =============================form start============================= |
19 | { | 19 | { |
20 | - path: '/form', | 20 | + path: 'form', |
21 | name: 'FormPage', | 21 | name: 'FormPage', |
22 | redirect: '/page-demo/form/basic', | 22 | redirect: '/page-demo/form/basic', |
23 | + component: getParentLayout('FormPage'), | ||
23 | meta: { | 24 | meta: { |
24 | title: 'routes.demo.page.form', | 25 | title: 'routes.demo.page.form', |
25 | }, | 26 | }, |
@@ -53,8 +54,9 @@ const page: AppRouteModule = { | @@ -53,8 +54,9 @@ const page: AppRouteModule = { | ||
53 | // =============================form end============================= | 54 | // =============================form end============================= |
54 | // =============================desc start============================= | 55 | // =============================desc start============================= |
55 | { | 56 | { |
56 | - path: '/desc', | 57 | + path: 'desc', |
57 | name: 'DescPage', | 58 | name: 'DescPage', |
59 | + component: getParentLayout('DescPage'), | ||
58 | redirect: '/page-demo/desc/basic', | 60 | redirect: '/page-demo/desc/basic', |
59 | meta: { | 61 | meta: { |
60 | title: 'routes.demo.page.desc', | 62 | title: 'routes.demo.page.desc', |
@@ -82,9 +84,11 @@ const page: AppRouteModule = { | @@ -82,9 +84,11 @@ const page: AppRouteModule = { | ||
82 | 84 | ||
83 | // =============================result start============================= | 85 | // =============================result start============================= |
84 | { | 86 | { |
85 | - path: '/result', | 87 | + path: 'result', |
86 | name: 'ResultPage', | 88 | name: 'ResultPage', |
87 | redirect: '/page-demo/result/success', | 89 | redirect: '/page-demo/result/success', |
90 | + component: getParentLayout('ResultPage'), | ||
91 | + | ||
88 | meta: { | 92 | meta: { |
89 | title: 'routes.demo.page.result', | 93 | title: 'routes.demo.page.result', |
90 | }, | 94 | }, |
@@ -111,8 +115,9 @@ const page: AppRouteModule = { | @@ -111,8 +115,9 @@ const page: AppRouteModule = { | ||
111 | 115 | ||
112 | // =============================account start============================= | 116 | // =============================account start============================= |
113 | { | 117 | { |
114 | - path: '/account', | 118 | + path: 'account', |
115 | name: 'AccountPage', | 119 | name: 'AccountPage', |
120 | + component: getParentLayout('AccountPage'), | ||
116 | redirect: '/page-demo/account/setting', | 121 | redirect: '/page-demo/account/setting', |
117 | meta: { | 122 | meta: { |
118 | title: 'routes.demo.page.account', | 123 | title: 'routes.demo.page.account', |
@@ -139,8 +144,9 @@ const page: AppRouteModule = { | @@ -139,8 +144,9 @@ const page: AppRouteModule = { | ||
139 | // =============================account end============================= | 144 | // =============================account end============================= |
140 | // =============================exception start============================= | 145 | // =============================exception start============================= |
141 | { | 146 | { |
142 | - path: '/exception', | 147 | + path: 'exception', |
143 | name: 'ExceptionPage', | 148 | name: 'ExceptionPage', |
149 | + component: getParentLayout('ExceptionPage'), | ||
144 | redirect: '/page-demo/exception/404', | 150 | redirect: '/page-demo/exception/404', |
145 | meta: { | 151 | meta: { |
146 | title: 'routes.demo.page.exception', | 152 | title: 'routes.demo.page.exception', |
@@ -211,8 +217,9 @@ const page: AppRouteModule = { | @@ -211,8 +217,9 @@ const page: AppRouteModule = { | ||
211 | // =============================exception end============================= | 217 | // =============================exception end============================= |
212 | // =============================list start============================= | 218 | // =============================list start============================= |
213 | { | 219 | { |
214 | - path: '/list', | 220 | + path: 'list', |
215 | name: 'ListPage', | 221 | name: 'ListPage', |
222 | + component: getParentLayout('ListPage'), | ||
216 | redirect: '/page-demo/list/card', | 223 | redirect: '/page-demo/list/card', |
217 | meta: { | 224 | meta: { |
218 | title: 'routes.demo.page.list', | 225 | title: 'routes.demo.page.list', |
src/router/routes/modules/demo/permission.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { getParentLayout, LAYOUT } from '/@/router/constant'; |
4 | import { RoleEnum } from '/@/enums/roleEnum'; | 4 | import { RoleEnum } from '/@/enums/roleEnum'; |
5 | 5 | ||
6 | const permission: AppRouteModule = { | 6 | const permission: AppRouteModule = { |
7 | - layout: { | ||
8 | - path: '/permission', | ||
9 | - name: 'Permission', | ||
10 | - component: PAGE_LAYOUT_COMPONENT, | ||
11 | - redirect: '/permission/front/page', | ||
12 | - meta: { | ||
13 | - icon: 'carbon:user-role', | ||
14 | - title: 'routes.demo.permission.permission', | ||
15 | - }, | 7 | + path: '/permission', |
8 | + name: 'Permission', | ||
9 | + component: LAYOUT, | ||
10 | + redirect: '/permission/front/page', | ||
11 | + meta: { | ||
12 | + icon: 'carbon:user-role', | ||
13 | + title: 'routes.demo.permission.permission', | ||
16 | }, | 14 | }, |
17 | 15 | ||
18 | - routes: [ | 16 | + children: [ |
19 | { | 17 | { |
20 | - path: '/front', | 18 | + path: 'front', |
21 | name: 'PermissionFrontDemo', | 19 | name: 'PermissionFrontDemo', |
20 | + component: getParentLayout('PermissionFrontDemo'), | ||
22 | meta: { | 21 | meta: { |
23 | title: 'routes.demo.permission.front', | 22 | title: 'routes.demo.permission.front', |
24 | }, | 23 | }, |
@@ -60,8 +59,9 @@ const permission: AppRouteModule = { | @@ -60,8 +59,9 @@ const permission: AppRouteModule = { | ||
60 | ], | 59 | ], |
61 | }, | 60 | }, |
62 | { | 61 | { |
63 | - path: '/back', | 62 | + path: 'back', |
64 | name: 'PermissionBackDemo', | 63 | name: 'PermissionBackDemo', |
64 | + component: getParentLayout('PermissionBackDemo'), | ||
65 | meta: { | 65 | meta: { |
66 | title: 'routes.demo.permission.back', | 66 | title: 'routes.demo.permission.back', |
67 | }, | 67 | }, |
src/router/routes/modules/demo/table.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const table: AppRouteModule = { | 5 | const table: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/table', | ||
8 | - name: 'TableDemo', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/table/basic', | ||
11 | - meta: { | ||
12 | - icon: 'ant-design:table-outlined', | ||
13 | - title: 'routes.demo.table.table', | ||
14 | - }, | 6 | + path: '/table', |
7 | + name: 'TableDemo', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/table/basic', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:table-outlined', | ||
12 | + title: 'routes.demo.table.table', | ||
15 | }, | 13 | }, |
16 | 14 | ||
17 | - routes: [ | 15 | + children: [ |
18 | { | 16 | { |
19 | - path: '/basic', | 17 | + path: 'basic', |
20 | name: 'TableBasicDemo', | 18 | name: 'TableBasicDemo', |
21 | component: () => import('/@/views/demo/table/Basic.vue'), | 19 | component: () => import('/@/views/demo/table/Basic.vue'), |
22 | meta: { | 20 | meta: { |
@@ -24,7 +22,7 @@ const table: AppRouteModule = { | @@ -24,7 +22,7 @@ const table: AppRouteModule = { | ||
24 | }, | 22 | }, |
25 | }, | 23 | }, |
26 | { | 24 | { |
27 | - path: '/treeTable', | 25 | + path: 'treeTable', |
28 | name: 'TreeTableDemo', | 26 | name: 'TreeTableDemo', |
29 | component: () => import('/@/views/demo/table/TreeTable.vue'), | 27 | component: () => import('/@/views/demo/table/TreeTable.vue'), |
30 | meta: { | 28 | meta: { |
@@ -32,7 +30,7 @@ const table: AppRouteModule = { | @@ -32,7 +30,7 @@ const table: AppRouteModule = { | ||
32 | }, | 30 | }, |
33 | }, | 31 | }, |
34 | { | 32 | { |
35 | - path: '/fetchTable', | 33 | + path: 'fetchTable', |
36 | name: 'FetchTableDemo', | 34 | name: 'FetchTableDemo', |
37 | component: () => import('/@/views/demo/table/FetchTable.vue'), | 35 | component: () => import('/@/views/demo/table/FetchTable.vue'), |
38 | meta: { | 36 | meta: { |
@@ -40,7 +38,7 @@ const table: AppRouteModule = { | @@ -40,7 +38,7 @@ const table: AppRouteModule = { | ||
40 | }, | 38 | }, |
41 | }, | 39 | }, |
42 | { | 40 | { |
43 | - path: '/fixedColumn', | 41 | + path: 'fixedColumn', |
44 | name: 'FixedColumnDemo', | 42 | name: 'FixedColumnDemo', |
45 | component: () => import('/@/views/demo/table/FixedColumn.vue'), | 43 | component: () => import('/@/views/demo/table/FixedColumn.vue'), |
46 | meta: { | 44 | meta: { |
@@ -48,7 +46,7 @@ const table: AppRouteModule = { | @@ -48,7 +46,7 @@ const table: AppRouteModule = { | ||
48 | }, | 46 | }, |
49 | }, | 47 | }, |
50 | { | 48 | { |
51 | - path: '/customerCell', | 49 | + path: 'customerCell', |
52 | name: 'CustomerCellDemo', | 50 | name: 'CustomerCellDemo', |
53 | component: () => import('/@/views/demo/table/CustomerCell.vue'), | 51 | component: () => import('/@/views/demo/table/CustomerCell.vue'), |
54 | meta: { | 52 | meta: { |
@@ -56,7 +54,7 @@ const table: AppRouteModule = { | @@ -56,7 +54,7 @@ const table: AppRouteModule = { | ||
56 | }, | 54 | }, |
57 | }, | 55 | }, |
58 | { | 56 | { |
59 | - path: '/formTable', | 57 | + path: 'formTable', |
60 | name: 'FormTableDemo', | 58 | name: 'FormTableDemo', |
61 | component: () => import('/@/views/demo/table/FormTable.vue'), | 59 | component: () => import('/@/views/demo/table/FormTable.vue'), |
62 | meta: { | 60 | meta: { |
@@ -64,7 +62,7 @@ const table: AppRouteModule = { | @@ -64,7 +62,7 @@ const table: AppRouteModule = { | ||
64 | }, | 62 | }, |
65 | }, | 63 | }, |
66 | { | 64 | { |
67 | - path: '/useTable', | 65 | + path: 'useTable', |
68 | name: 'UseTableDemo', | 66 | name: 'UseTableDemo', |
69 | component: () => import('/@/views/demo/table/UseTable.vue'), | 67 | component: () => import('/@/views/demo/table/UseTable.vue'), |
70 | meta: { | 68 | meta: { |
@@ -72,7 +70,7 @@ const table: AppRouteModule = { | @@ -72,7 +70,7 @@ const table: AppRouteModule = { | ||
72 | }, | 70 | }, |
73 | }, | 71 | }, |
74 | { | 72 | { |
75 | - path: '/refTable', | 73 | + path: 'refTable', |
76 | name: 'RefTableDemo', | 74 | name: 'RefTableDemo', |
77 | component: () => import('/@/views/demo/table/RefTable.vue'), | 75 | component: () => import('/@/views/demo/table/RefTable.vue'), |
78 | meta: { | 76 | meta: { |
@@ -80,7 +78,7 @@ const table: AppRouteModule = { | @@ -80,7 +78,7 @@ const table: AppRouteModule = { | ||
80 | }, | 78 | }, |
81 | }, | 79 | }, |
82 | { | 80 | { |
83 | - path: '/multipleHeader', | 81 | + path: 'multipleHeader', |
84 | name: 'MultipleHeaderDemo', | 82 | name: 'MultipleHeaderDemo', |
85 | component: () => import('/@/views/demo/table/MultipleHeader.vue'), | 83 | component: () => import('/@/views/demo/table/MultipleHeader.vue'), |
86 | meta: { | 84 | meta: { |
@@ -88,7 +86,7 @@ const table: AppRouteModule = { | @@ -88,7 +86,7 @@ const table: AppRouteModule = { | ||
88 | }, | 86 | }, |
89 | }, | 87 | }, |
90 | { | 88 | { |
91 | - path: '/mergeHeader', | 89 | + path: 'mergeHeader', |
92 | name: 'MergeHeaderDemo', | 90 | name: 'MergeHeaderDemo', |
93 | component: () => import('/@/views/demo/table/MergeHeader.vue'), | 91 | component: () => import('/@/views/demo/table/MergeHeader.vue'), |
94 | meta: { | 92 | meta: { |
@@ -96,7 +94,7 @@ const table: AppRouteModule = { | @@ -96,7 +94,7 @@ const table: AppRouteModule = { | ||
96 | }, | 94 | }, |
97 | }, | 95 | }, |
98 | { | 96 | { |
99 | - path: '/expandTable', | 97 | + path: 'expandTable', |
100 | name: 'ExpandTableDemo', | 98 | name: 'ExpandTableDemo', |
101 | component: () => import('/@/views/demo/table/ExpandTable.vue'), | 99 | component: () => import('/@/views/demo/table/ExpandTable.vue'), |
102 | meta: { | 100 | meta: { |
@@ -104,7 +102,7 @@ const table: AppRouteModule = { | @@ -104,7 +102,7 @@ const table: AppRouteModule = { | ||
104 | }, | 102 | }, |
105 | }, | 103 | }, |
106 | { | 104 | { |
107 | - path: '/fixedHeight', | 105 | + path: 'fixedHeight', |
108 | name: 'FixedHeightDemo', | 106 | name: 'FixedHeightDemo', |
109 | component: () => import('/@/views/demo/table/FixedHeight.vue'), | 107 | component: () => import('/@/views/demo/table/FixedHeight.vue'), |
110 | meta: { | 108 | meta: { |
@@ -112,7 +110,7 @@ const table: AppRouteModule = { | @@ -112,7 +110,7 @@ const table: AppRouteModule = { | ||
112 | }, | 110 | }, |
113 | }, | 111 | }, |
114 | { | 112 | { |
115 | - path: '/footerTable', | 113 | + path: 'footerTable', |
116 | name: 'FooterTableDemo', | 114 | name: 'FooterTableDemo', |
117 | component: () => import('/@/views/demo/table/FooterTable.vue'), | 115 | component: () => import('/@/views/demo/table/FooterTable.vue'), |
118 | meta: { | 116 | meta: { |
@@ -120,7 +118,7 @@ const table: AppRouteModule = { | @@ -120,7 +118,7 @@ const table: AppRouteModule = { | ||
120 | }, | 118 | }, |
121 | }, | 119 | }, |
122 | { | 120 | { |
123 | - path: '/editCellTable', | 121 | + path: 'editCellTable', |
124 | name: 'EditCellTableDemo', | 122 | name: 'EditCellTableDemo', |
125 | component: () => import('/@/views/demo/table/EditCellTable.vue'), | 123 | component: () => import('/@/views/demo/table/EditCellTable.vue'), |
126 | meta: { | 124 | meta: { |
@@ -128,7 +126,7 @@ const table: AppRouteModule = { | @@ -128,7 +126,7 @@ const table: AppRouteModule = { | ||
128 | }, | 126 | }, |
129 | }, | 127 | }, |
130 | { | 128 | { |
131 | - path: '/editRowTable', | 129 | + path: 'editRowTable', |
132 | name: 'EditRowTableDemo', | 130 | name: 'EditRowTableDemo', |
133 | component: () => import('/@/views/demo/table/EditRowTable.vue'), | 131 | component: () => import('/@/views/demo/table/EditRowTable.vue'), |
134 | meta: { | 132 | meta: { |
src/router/routes/modules/demo/tree.ts
1 | import type { AppRouteModule } from '/@/router/types'; | 1 | import type { AppRouteModule } from '/@/router/types'; |
2 | 2 | ||
3 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | 3 | +import { LAYOUT } from '/@/router/constant'; |
4 | 4 | ||
5 | const tree: AppRouteModule = { | 5 | const tree: AppRouteModule = { |
6 | - layout: { | ||
7 | - path: '/tree', | ||
8 | - name: 'TreeDemo', | ||
9 | - component: PAGE_LAYOUT_COMPONENT, | ||
10 | - redirect: '/tree/basic', | ||
11 | - meta: { | ||
12 | - icon: 'clarity:tree-view-line', | ||
13 | - title: 'routes.demo.tree.tree', | ||
14 | - }, | 6 | + path: '/tree', |
7 | + name: 'TreeDemo', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/tree/basic', | ||
10 | + meta: { | ||
11 | + icon: 'clarity:tree-view-line', | ||
12 | + title: 'routes.demo.tree.tree', | ||
15 | }, | 13 | }, |
16 | - routes: [ | 14 | + children: [ |
17 | { | 15 | { |
18 | - path: '/basic', | 16 | + path: 'basic', |
19 | name: 'BasicTreeDemo', | 17 | name: 'BasicTreeDemo', |
20 | component: () => import('/@/views/demo/tree/index.vue'), | 18 | component: () => import('/@/views/demo/tree/index.vue'), |
21 | meta: { | 19 | meta: { |
@@ -23,7 +21,7 @@ const tree: AppRouteModule = { | @@ -23,7 +21,7 @@ const tree: AppRouteModule = { | ||
23 | }, | 21 | }, |
24 | }, | 22 | }, |
25 | { | 23 | { |
26 | - path: '/editTree', | 24 | + path: 'editTree', |
27 | name: 'EditTreeDemo', | 25 | name: 'EditTreeDemo', |
28 | component: () => import('/@/views/demo/tree/EditTree.vue'), | 26 | component: () => import('/@/views/demo/tree/EditTree.vue'), |
29 | meta: { | 27 | meta: { |
@@ -31,7 +29,7 @@ const tree: AppRouteModule = { | @@ -31,7 +29,7 @@ const tree: AppRouteModule = { | ||
31 | }, | 29 | }, |
32 | }, | 30 | }, |
33 | { | 31 | { |
34 | - path: '/actionTree', | 32 | + path: 'actionTree', |
35 | name: 'ActionTreeDemo', | 33 | name: 'ActionTreeDemo', |
36 | component: () => import('/@/views/demo/tree/ActionTree.vue'), | 34 | component: () => import('/@/views/demo/tree/ActionTree.vue'), |
37 | meta: { | 35 | meta: { |
src/router/routes/modules/home.ts
0 → 100644
1 | +import type { AppRouteModule } from '/@/router/types'; | ||
2 | + | ||
3 | +import { LAYOUT } from '/@/router/constant'; | ||
4 | + | ||
5 | +const dashboard: AppRouteModule = { | ||
6 | + path: '/home', | ||
7 | + name: 'Home', | ||
8 | + component: LAYOUT, | ||
9 | + redirect: '/home/welcome', | ||
10 | + meta: { | ||
11 | + icon: 'ant-design:home-outlined', | ||
12 | + title: 'routes.dashboard.welcome', | ||
13 | + }, | ||
14 | + children: [ | ||
15 | + { | ||
16 | + path: 'welcome', | ||
17 | + name: 'Welcome', | ||
18 | + component: () => import('/@/views/dashboard/welcome/index.vue'), | ||
19 | + meta: { | ||
20 | + title: 'routes.dashboard.welcome', | ||
21 | + affix: true, | ||
22 | + icon: 'ant-design:home-outlined', | ||
23 | + }, | ||
24 | + }, | ||
25 | + ], | ||
26 | +}; | ||
27 | + | ||
28 | +export default dashboard; |
src/router/types.d.ts
1 | import type { RouteRecordRaw } from 'vue-router'; | 1 | import type { RouteRecordRaw } from 'vue-router'; |
2 | import { RoleEnum } from '/@/enums/roleEnum'; | 2 | import { RoleEnum } from '/@/enums/roleEnum'; |
3 | +import Component from '/@/components/types'; | ||
3 | export interface RouteMeta { | 4 | export interface RouteMeta { |
4 | // title | 5 | // title |
5 | title: string; | 6 | title: string; |
@@ -24,24 +25,23 @@ export interface RouteMeta { | @@ -24,24 +25,23 @@ export interface RouteMeta { | ||
24 | // Whether the route has been dynamically added | 25 | // Whether the route has been dynamically added |
25 | hideBreadcrumb?: boolean; | 26 | hideBreadcrumb?: boolean; |
26 | 27 | ||
27 | - // disabled redirect | ||
28 | - disabledRedirect?: boolean; | ||
29 | - | ||
30 | // close loading | 28 | // close loading |
31 | afterCloseLoading?: boolean; | 29 | afterCloseLoading?: boolean; |
32 | // Is it in the tab | 30 | // Is it in the tab |
33 | inTab?: boolean; | 31 | inTab?: boolean; |
34 | // Carrying parameters | 32 | // Carrying parameters |
35 | carryParam?: boolean; | 33 | carryParam?: boolean; |
34 | + | ||
35 | + single?: boolean; | ||
36 | } | 36 | } |
37 | 37 | ||
38 | export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> { | 38 | export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> { |
39 | name: string; | 39 | name: string; |
40 | meta: RouteMeta; | 40 | meta: RouteMeta; |
41 | - component?: any; | ||
42 | - components?: any; | 41 | + component?: Component; |
42 | + components?: Component; | ||
43 | children?: AppRouteRecordRaw[]; | 43 | children?: AppRouteRecordRaw[]; |
44 | - props?: any; | 44 | + props?: Record<string, any>; |
45 | fullPath?: string; | 45 | fullPath?: string; |
46 | } | 46 | } |
47 | export interface MenuTag { | 47 | export interface MenuTag { |
@@ -75,11 +75,12 @@ export interface MenuModule { | @@ -75,11 +75,12 @@ export interface MenuModule { | ||
75 | menu: Menu; | 75 | menu: Menu; |
76 | } | 76 | } |
77 | 77 | ||
78 | -interface RouteModule { | ||
79 | - layout: AppRouteRecordRaw; | ||
80 | - routes: AppRouteRecordRaw[]; | ||
81 | - children?: AppRouteRecordRaw[]; | ||
82 | - component?: any; | ||
83 | -} | 78 | +// interface RouteModule { |
79 | +// layout: AppRouteRecordRaw; | ||
80 | +// routes: AppRouteRecordRaw[]; | ||
81 | +// children?: AppRouteRecordRaw[]; | ||
82 | +// component?: Component; | ||
83 | +// } | ||
84 | 84 | ||
85 | -export type AppRouteModule = RouteModule | AppRouteRecordRaw; | 85 | +// export type AppRouteModule = RouteModule | AppRouteRecordRaw; |
86 | +export type AppRouteModule = AppRouteRecordRaw; |
src/store/modules/permission.ts
1 | -import { REDIRECT_ROUTE } from '/@/router/constant'; | ||
2 | import type { AppRouteRecordRaw, Menu } from '/@/router/types'; | 1 | import type { AppRouteRecordRaw, Menu } from '/@/router/types'; |
3 | import store from '/@/store/index'; | 2 | import store from '/@/store/index'; |
4 | import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | 3 | import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; |
@@ -15,15 +14,13 @@ import { filter } from '/@/utils/helper/treeHelper'; | @@ -15,15 +14,13 @@ import { filter } from '/@/utils/helper/treeHelper'; | ||
15 | import { toRaw } from 'vue'; | 14 | import { toRaw } from 'vue'; |
16 | import { getMenuListById } from '/@/api/sys/menu'; | 15 | import { getMenuListById } from '/@/api/sys/menu'; |
17 | 16 | ||
18 | -import { genRouteModule, transformObjToRoute } from '/@/utils/helper/routeHelper'; | ||
19 | -import { transformRouteToMenu } from '/@/utils/helper/menuHelper'; | 17 | +import { transformObjToRoute } from '/@/router/helper/routeHelper'; |
18 | +import { transformRouteToMenu } from '/@/router/helper/menuHelper'; | ||
20 | 19 | ||
21 | import { useMessage } from '/@/hooks/web/useMessage'; | 20 | import { useMessage } from '/@/hooks/web/useMessage'; |
22 | // import { warn } from '/@/utils/log'; | 21 | // import { warn } from '/@/utils/log'; |
23 | import { useI18n } from '/@/hooks/web/useI18n'; | 22 | import { useI18n } from '/@/hooks/web/useI18n'; |
24 | 23 | ||
25 | -const { t } = useI18n(); | ||
26 | - | ||
27 | const { createMessage } = useMessage(); | 24 | const { createMessage } = useMessage(); |
28 | const NAME = 'permission'; | 25 | const NAME = 'permission'; |
29 | hotModuleUnregisterModule(NAME); | 26 | hotModuleUnregisterModule(NAME); |
@@ -87,6 +84,7 @@ class Permission extends VuexModule { | @@ -87,6 +84,7 @@ class Permission extends VuexModule { | ||
87 | 84 | ||
88 | @Action | 85 | @Action |
89 | async buildRoutesAction(id?: number | string): Promise<AppRouteRecordRaw[]> { | 86 | async buildRoutesAction(id?: number | string): Promise<AppRouteRecordRaw[]> { |
87 | + const { t } = useI18n(); | ||
90 | let routes: AppRouteRecordRaw[] = []; | 88 | let routes: AppRouteRecordRaw[] = []; |
91 | const roleList = toRaw(userStore.getRoleListState); | 89 | const roleList = toRaw(userStore.getRoleListState); |
92 | 90 | ||
@@ -95,17 +93,15 @@ class Permission extends VuexModule { | @@ -95,17 +93,15 @@ class Permission extends VuexModule { | ||
95 | // role permissions | 93 | // role permissions |
96 | if (permissionMode === PermissionModeEnum.ROLE) { | 94 | if (permissionMode === PermissionModeEnum.ROLE) { |
97 | routes = filter(asyncRoutes, (route) => { | 95 | routes = filter(asyncRoutes, (route) => { |
98 | - const { meta } = route; | ||
99 | - const { roles } = meta!; | 96 | + const { meta } = route as AppRouteRecordRaw; |
97 | + const { roles } = meta || {}; | ||
100 | if (!roles) return true; | 98 | if (!roles) return true; |
101 | return roleList.some((role) => roles.includes(role)); | 99 | return roleList.some((role) => roles.includes(role)); |
102 | }); | 100 | }); |
103 | // 如果确定不需要做后台动态权限,请将下面整个判断注释 | 101 | // 如果确定不需要做后台动态权限,请将下面整个判断注释 |
104 | } else if (permissionMode === PermissionModeEnum.BACK) { | 102 | } else if (permissionMode === PermissionModeEnum.BACK) { |
105 | - const messageKey = 'loadMenu'; | ||
106 | createMessage.loading({ | 103 | createMessage.loading({ |
107 | content: t('sys.app.menuLoading'), | 104 | content: t('sys.app.menuLoading'), |
108 | - key: messageKey, | ||
109 | duration: 1, | 105 | duration: 1, |
110 | }); | 106 | }); |
111 | // 这里获取后台路由菜单逻辑自行修改 | 107 | // 这里获取后台路由菜单逻辑自行修改 |
@@ -118,10 +114,10 @@ class Permission extends VuexModule { | @@ -118,10 +114,10 @@ class Permission extends VuexModule { | ||
118 | routeList = transformObjToRoute(routeList); | 114 | routeList = transformObjToRoute(routeList); |
119 | // 后台路由转菜单结构 | 115 | // 后台路由转菜单结构 |
120 | const backMenuList = transformRouteToMenu(routeList); | 116 | const backMenuList = transformRouteToMenu(routeList); |
117 | + | ||
121 | this.commitBackMenuListState(backMenuList); | 118 | this.commitBackMenuListState(backMenuList); |
122 | - // 生成路由 | ||
123 | - routes = genRouteModule(routeList) as AppRouteRecordRaw[]; | ||
124 | - routes.push(REDIRECT_ROUTE); | 119 | + |
120 | + routes = routeList; | ||
125 | } | 121 | } |
126 | return routes; | 122 | return routes; |
127 | } | 123 | } |
src/store/modules/tab.ts
1 | -import { computed, toRaw } from 'vue'; | ||
2 | -import type { AppRouteRecordRaw, RouteMeta } from '/@/router/types.d'; | 1 | +import { toRaw } from 'vue'; |
3 | 2 | ||
4 | import { unref } from 'vue'; | 3 | import { unref } from 'vue'; |
5 | import { Action, Module, Mutation, VuexModule, getModule } from 'vuex-module-decorators'; | 4 | import { Action, Module, Mutation, VuexModule, getModule } from 'vuex-module-decorators'; |
6 | import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | 5 | import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; |
7 | 6 | ||
8 | import { PageEnum } from '/@/enums/pageEnum'; | 7 | import { PageEnum } from '/@/enums/pageEnum'; |
9 | -import { appStore } from '/@/store/modules/app'; | ||
10 | import { userStore } from './user'; | 8 | import { userStore } from './user'; |
11 | 9 | ||
12 | import store from '/@/store'; | 10 | import store from '/@/store'; |
13 | import router from '/@/router'; | 11 | import router from '/@/router'; |
14 | import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant'; | 12 | import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant'; |
15 | -import { getCurrentTo } from '/@/utils/helper/routeHelper'; | 13 | +import { RouteLocationNormalized, RouteLocationRaw } from 'vue-router'; |
14 | +import { getRoute } from '/@/router/helper/routeHelper'; | ||
15 | +import { useGo, useRedo } from '/@/hooks/web/usePage'; | ||
16 | 16 | ||
17 | -type CacheName = string | symbol | null | undefined; | ||
18 | - | ||
19 | -/** | ||
20 | - * @description: vuex Tab模块 | ||
21 | - */ | ||
22 | // declare namespace TabsStore { | 17 | // declare namespace TabsStore { |
23 | -export interface TabItem { | ||
24 | - fullPath: string; | ||
25 | - path?: string; | ||
26 | - params?: any; | ||
27 | - query?: any; | ||
28 | - name?: CacheName; | ||
29 | - meta?: RouteMeta; | ||
30 | -} | ||
31 | 18 | ||
32 | const NAME = 'tab'; | 19 | const NAME = 'tab'; |
33 | 20 | ||
34 | hotModuleUnregisterModule(NAME); | 21 | hotModuleUnregisterModule(NAME); |
35 | 22 | ||
36 | -const getOpenKeepAliveRef = computed(() => appStore.getProjectConfig.openKeepAlive); | 23 | +export const PAGE_LAYOUT_KEY = '__PAGE_LAYOUT__'; |
24 | + | ||
25 | +function isGotoPage() { | ||
26 | + const go = useGo(); | ||
27 | + go(unref(router.currentRoute).path, true); | ||
28 | +} | ||
37 | 29 | ||
38 | @Module({ namespaced: true, name: NAME, dynamic: true, store }) | 30 | @Module({ namespaced: true, name: NAME, dynamic: true, store }) |
39 | class Tab extends VuexModule { | 31 | class Tab extends VuexModule { |
40 | - // tab list | ||
41 | - tabsState: TabItem[] = []; | ||
42 | - // tab cache list | ||
43 | - keepAliveTabsState: CacheName[] = []; | 32 | + cachedMapState = new Map<string, string[]>(); |
44 | 33 | ||
45 | - currentContextMenuIndexState = -1; | ||
46 | - | ||
47 | - currentContextMenuState: TabItem | null = null; | 34 | + // tab list |
35 | + tabsState: RouteLocationNormalized[] = []; | ||
48 | 36 | ||
49 | // Last route change | 37 | // Last route change |
50 | - lastChangeRouteState: AppRouteRecordRaw | null = null; | 38 | + lastChangeRouteState: RouteLocationNormalized | null = null; |
39 | + | ||
40 | + lastDragEndIndexState = 0; | ||
51 | 41 | ||
52 | get getTabsState() { | 42 | get getTabsState() { |
53 | return this.tabsState; | 43 | return this.tabsState; |
@@ -57,56 +47,93 @@ class Tab extends VuexModule { | @@ -57,56 +47,93 @@ class Tab extends VuexModule { | ||
57 | return this.lastChangeRouteState; | 47 | return this.lastChangeRouteState; |
58 | } | 48 | } |
59 | 49 | ||
60 | - get getCurrentContextMenuIndexState() { | ||
61 | - return this.currentContextMenuIndexState; | ||
62 | - } | ||
63 | - | ||
64 | - get getCurrentContextMenuState() { | ||
65 | - return this.currentContextMenuState; | 50 | + get getCurrentTab(): RouteLocationNormalized { |
51 | + const route = unref(router.currentRoute); | ||
52 | + return this.tabsState.find((item) => item.path === route.path)!; | ||
66 | } | 53 | } |
67 | 54 | ||
68 | - get getKeepAliveTabsState() { | ||
69 | - return this.keepAliveTabsState; | 55 | + get getCachedMapState(): Map<string, string[]> { |
56 | + return this.cachedMapState; | ||
70 | } | 57 | } |
71 | 58 | ||
72 | - get getCurrentTab(): TabItem { | ||
73 | - const route = unref(router.currentRoute); | ||
74 | - return this.tabsState.find((item) => item.path === route.path)!; | 59 | + get getLastDragEndIndexState(): number { |
60 | + return this.lastDragEndIndexState; | ||
75 | } | 61 | } |
76 | 62 | ||
77 | @Mutation | 63 | @Mutation |
78 | - commitLastChangeRouteState(route: AppRouteRecordRaw): void { | 64 | + commitLastChangeRouteState(route: RouteLocationNormalized): void { |
79 | if (!userStore.getTokenState) return; | 65 | if (!userStore.getTokenState) return; |
80 | this.lastChangeRouteState = route; | 66 | this.lastChangeRouteState = route; |
81 | } | 67 | } |
82 | 68 | ||
83 | @Mutation | 69 | @Mutation |
84 | commitClearCache(): void { | 70 | commitClearCache(): void { |
85 | - this.keepAliveTabsState = []; | 71 | + this.cachedMapState = new Map(); |
86 | } | 72 | } |
87 | 73 | ||
88 | @Mutation | 74 | @Mutation |
89 | - commitCurrentContextMenuIndexState(index: number): void { | ||
90 | - this.currentContextMenuIndexState = index; | 75 | + goToPage() { |
76 | + const go = useGo(); | ||
77 | + const len = this.tabsState.length; | ||
78 | + const { path } = unref(router.currentRoute); | ||
79 | + | ||
80 | + let toPath: PageEnum | string = PageEnum.BASE_HOME; | ||
81 | + | ||
82 | + if (len > 0) { | ||
83 | + const page = this.tabsState[len - 1]; | ||
84 | + const p = page.fullPath || page.path; | ||
85 | + if (p) { | ||
86 | + toPath = p; | ||
87 | + } | ||
88 | + } | ||
89 | + // Jump to the current page and report an error | ||
90 | + path !== toPath && go(toPath as PageEnum, true); | ||
91 | } | 91 | } |
92 | 92 | ||
93 | @Mutation | 93 | @Mutation |
94 | - commitCurrentContextMenuState(item: TabItem): void { | ||
95 | - this.currentContextMenuState = item; | 94 | + commitCachedMapState(): void { |
95 | + const cacheMap = new Map<string, string[]>(); | ||
96 | + | ||
97 | + const pageCacheSet = new Set<string>(); | ||
98 | + this.tabsState.forEach((tab) => { | ||
99 | + const item = getRoute(tab); | ||
100 | + const needAuth = !item.meta.ignoreAuth; | ||
101 | + if (item.meta.affix) { | ||
102 | + const name = item.name as string; | ||
103 | + pageCacheSet.add(name); | ||
104 | + } else if (item.matched && needAuth) { | ||
105 | + const matched = item.matched; | ||
106 | + const len = matched.length; | ||
107 | + | ||
108 | + if (len < 2) return; | ||
109 | + | ||
110 | + for (let i = 0; i < matched.length; i++) { | ||
111 | + const key = matched[i].name as string; | ||
112 | + | ||
113 | + if (i < 2) { | ||
114 | + pageCacheSet.add(key); | ||
115 | + } | ||
116 | + if (i < len - 1) { | ||
117 | + const { meta, name } = matched[i + 1]; | ||
118 | + if (meta && (meta.affix || needAuth)) { | ||
119 | + const mapList = cacheMap.get(key) || []; | ||
120 | + if (!mapList.includes(name as string)) { | ||
121 | + mapList.push(name as string); | ||
122 | + } | ||
123 | + cacheMap.set(key, mapList); | ||
124 | + } | ||
125 | + } | ||
126 | + } | ||
127 | + } | ||
128 | + }); | ||
129 | + | ||
130 | + cacheMap.set(PAGE_LAYOUT_KEY, Array.from(pageCacheSet)); | ||
131 | + this.cachedMapState = cacheMap; | ||
96 | } | 132 | } |
97 | 133 | ||
98 | - /** | ||
99 | - * @description: add tab | ||
100 | - */ | ||
101 | @Mutation | 134 | @Mutation |
102 | - commitAddTab(route: AppRouteRecordRaw | TabItem): void { | ||
103 | - const { path, name, meta, fullPath, params, query } = route as TabItem; | ||
104 | - // 404 页面不需要添加tab | ||
105 | - if (path === PageEnum.ERROR_PAGE || !name) { | ||
106 | - return; | ||
107 | - } else if ([REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)) { | ||
108 | - return; | ||
109 | - } | 135 | + commitTabRoutesState(route: RouteLocationNormalized) { |
136 | + const { path, fullPath, params, query } = route; | ||
110 | 137 | ||
111 | let updateIndex = -1; | 138 | let updateIndex = -1; |
112 | // 已经存在的页面,不重复添加tab | 139 | // 已经存在的页面,不重复添加tab |
@@ -123,39 +150,18 @@ class Tab extends VuexModule { | @@ -123,39 +150,18 @@ class Tab extends VuexModule { | ||
123 | this.tabsState.splice(updateIndex, 1, curTab); | 150 | this.tabsState.splice(updateIndex, 1, curTab); |
124 | return; | 151 | return; |
125 | } | 152 | } |
126 | - this.tabsState.push({ path, fullPath, name, meta, params, query }); | ||
127 | - if (unref(getOpenKeepAliveRef) && name) { | ||
128 | - const noKeepAlive = meta && meta.ignoreKeepAlive; | ||
129 | - const hasName = this.keepAliveTabsState.includes(name); | ||
130 | - !noKeepAlive && !hasName && this.keepAliveTabsState.push(name); | ||
131 | - } | 153 | + this.tabsState.push(route); |
132 | } | 154 | } |
133 | 155 | ||
134 | /** | 156 | /** |
135 | * @description: close tab | 157 | * @description: close tab |
136 | */ | 158 | */ |
137 | @Mutation | 159 | @Mutation |
138 | - commitCloseTab(route: AppRouteRecordRaw | TabItem): void { | ||
139 | - try { | ||
140 | - const { fullPath, name, meta: { affix } = {} } = route; | ||
141 | - if (affix) return; | ||
142 | - const index = this.tabsState.findIndex((item) => item.fullPath === fullPath); | ||
143 | - index !== -1 && this.tabsState.splice(index, 1); | ||
144 | - | ||
145 | - if (unref(getOpenKeepAliveRef) && name) { | ||
146 | - const i = this.keepAliveTabsState.findIndex((item) => item === name); | ||
147 | - i !== -1 && this.keepAliveTabsState.splice(i, 1); | ||
148 | - } | ||
149 | - } catch (error) {} | ||
150 | - } | ||
151 | - | ||
152 | - @Mutation | ||
153 | - commitCloseTabKeepAlive(route: AppRouteRecordRaw | TabItem): void { | ||
154 | - const { name } = route; | ||
155 | - if (unref(getOpenKeepAliveRef) && name) { | ||
156 | - const i = this.keepAliveTabsState.findIndex((item) => item === name); | ||
157 | - i !== -1 && toRaw(this.keepAliveTabsState).splice(i, 1); | ||
158 | - } | 160 | + commitCloseTab(route: RouteLocationNormalized): void { |
161 | + const { fullPath, meta: { affix } = {} } = route; | ||
162 | + if (affix) return; | ||
163 | + const index = this.tabsState.findIndex((item) => item.fullPath === fullPath); | ||
164 | + index !== -1 && this.tabsState.splice(index, 1); | ||
159 | } | 165 | } |
160 | 166 | ||
161 | @Mutation | 167 | @Mutation |
@@ -163,16 +169,12 @@ class Tab extends VuexModule { | @@ -163,16 +169,12 @@ class Tab extends VuexModule { | ||
163 | this.tabsState = this.tabsState.filter((item) => { | 169 | this.tabsState = this.tabsState.filter((item) => { |
164 | return item.meta && item.meta.affix; | 170 | return item.meta && item.meta.affix; |
165 | }); | 171 | }); |
166 | - const names = this.tabsState.map((item) => item.name); | ||
167 | - this.keepAliveTabsState = names as string[]; | ||
168 | } | 172 | } |
169 | 173 | ||
170 | @Mutation | 174 | @Mutation |
171 | commitResetState(): void { | 175 | commitResetState(): void { |
172 | this.tabsState = []; | 176 | this.tabsState = []; |
173 | - this.currentContextMenuState = null; | ||
174 | - this.currentContextMenuIndexState = -1; | ||
175 | - this.keepAliveTabsState = []; | 177 | + this.cachedMapState = new Map(); |
176 | } | 178 | } |
177 | 179 | ||
178 | @Mutation | 180 | @Mutation |
@@ -181,73 +183,149 @@ class Tab extends VuexModule { | @@ -181,73 +183,149 @@ class Tab extends VuexModule { | ||
181 | 183 | ||
182 | this.tabsState.splice(oldIndex, 1); | 184 | this.tabsState.splice(oldIndex, 1); |
183 | this.tabsState.splice(newIndex, 0, currentTab); | 185 | this.tabsState.splice(newIndex, 0, currentTab); |
186 | + this.lastDragEndIndexState = this.lastDragEndIndexState + 1; | ||
184 | } | 187 | } |
185 | 188 | ||
186 | @Mutation | 189 | @Mutation |
187 | - closeMultipleTab({ pathList, nameList }: { pathList: string[]; nameList: string[] }): void { | 190 | + closeMultipleTab({ pathList }: { pathList: string[] }): void { |
188 | this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath)); | 191 | this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath)); |
189 | - if (unref(getOpenKeepAliveRef) && nameList) { | ||
190 | - this.keepAliveTabsState = toRaw(this.keepAliveTabsState).filter( | ||
191 | - (item) => !nameList.includes(item as string) | ||
192 | - ); | 192 | + } |
193 | + | ||
194 | + @Action | ||
195 | + addTabAction(route: RouteLocationNormalized) { | ||
196 | + const { path, name } = route; | ||
197 | + // 404 页面不需要添加tab | ||
198 | + if ( | ||
199 | + path === PageEnum.ERROR_PAGE || | ||
200 | + !name || | ||
201 | + [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string) | ||
202 | + ) { | ||
203 | + return; | ||
204 | + } | ||
205 | + this.commitTabRoutesState(getRoute(route)); | ||
206 | + | ||
207 | + this.commitCachedMapState(); | ||
208 | + } | ||
209 | + | ||
210 | + @Mutation | ||
211 | + commitRedoPage() { | ||
212 | + const route = router.currentRoute.value; | ||
213 | + | ||
214 | + for (const [key, value] of this.cachedMapState) { | ||
215 | + const index = value.findIndex((item) => item === (route.name as string)); | ||
216 | + if (index === -1) { | ||
217 | + continue; | ||
218 | + } | ||
219 | + if (value.length === 1) { | ||
220 | + this.cachedMapState.delete(key); | ||
221 | + continue; | ||
222 | + } | ||
223 | + value.splice(index, 1); | ||
224 | + this.cachedMapState.set(key, value); | ||
225 | + } | ||
226 | + const redo = useRedo(); | ||
227 | + redo(); | ||
228 | + } | ||
229 | + | ||
230 | + @Action | ||
231 | + closeAllTabAction() { | ||
232 | + this.commitCloseAllTab(); | ||
233 | + this.commitClearCache(); | ||
234 | + this.goToPage(); | ||
235 | + } | ||
236 | + | ||
237 | + @Action | ||
238 | + closeTabAction(tab: RouteLocationNormalized) { | ||
239 | + function getObj(tabItem: RouteLocationNormalized) { | ||
240 | + const { params, path, query } = tabItem; | ||
241 | + return { | ||
242 | + params: params || {}, | ||
243 | + path, | ||
244 | + query: query || {}, | ||
245 | + }; | ||
246 | + } | ||
247 | + const { currentRoute, replace } = router; | ||
248 | + | ||
249 | + const { path } = unref(currentRoute); | ||
250 | + if (path !== tab.path) { | ||
251 | + // Closed is not the activation tab | ||
252 | + this.commitCloseTab(tab); | ||
253 | + return; | ||
254 | + } | ||
255 | + | ||
256 | + // Closed is activated atb | ||
257 | + let toObj: RouteLocationRaw = {}; | ||
258 | + | ||
259 | + const index = this.getTabsState.findIndex((item) => item.path === path); | ||
260 | + | ||
261 | + // If the current is the leftmost tab | ||
262 | + if (index === 0) { | ||
263 | + // There is only one tab, then jump to the homepage, otherwise jump to the right tab | ||
264 | + if (this.getTabsState.length === 1) { | ||
265 | + toObj = PageEnum.BASE_HOME; | ||
266 | + } else { | ||
267 | + // Jump to the right tab | ||
268 | + const page = this.getTabsState[index + 1]; | ||
269 | + toObj = getObj(page); | ||
270 | + } | ||
271 | + } else { | ||
272 | + // Close the current tab | ||
273 | + const page = this.getTabsState[index - 1]; | ||
274 | + toObj = getObj(page); | ||
193 | } | 275 | } |
276 | + this.commitCloseTab(currentRoute.value); | ||
277 | + replace(toObj); | ||
194 | } | 278 | } |
195 | 279 | ||
196 | @Action | 280 | @Action |
197 | - closeLeftTabAction(route: AppRouteRecordRaw | TabItem): void { | 281 | + closeTabByKeyAction(key: string) { |
282 | + const index = this.tabsState.findIndex((item) => (item.fullPath || item.path) === key); | ||
283 | + index !== -1 && this.closeTabAction(this.tabsState[index]); | ||
284 | + } | ||
285 | + | ||
286 | + @Action | ||
287 | + closeLeftTabAction(route: RouteLocationNormalized): void { | ||
198 | const index = this.tabsState.findIndex((item) => item.path === route.path); | 288 | const index = this.tabsState.findIndex((item) => item.path === route.path); |
199 | 289 | ||
200 | if (index > 0) { | 290 | if (index > 0) { |
201 | const leftTabs = this.tabsState.slice(0, index); | 291 | const leftTabs = this.tabsState.slice(0, index); |
202 | const pathList: string[] = []; | 292 | const pathList: string[] = []; |
203 | - const nameList: string[] = []; | ||
204 | for (const item of leftTabs) { | 293 | for (const item of leftTabs) { |
205 | const affix = item.meta ? item.meta.affix : false; | 294 | const affix = item.meta ? item.meta.affix : false; |
206 | if (!affix) { | 295 | if (!affix) { |
207 | pathList.push(item.fullPath); | 296 | pathList.push(item.fullPath); |
208 | - nameList.push(item.name as string); | ||
209 | } | 297 | } |
210 | } | 298 | } |
211 | - this.closeMultipleTab({ pathList, nameList }); | ||
212 | - } | ||
213 | - } | ||
214 | - | ||
215 | - @Action | ||
216 | - addTabByPathAction(): void { | ||
217 | - const toRoute = getCurrentTo(); | ||
218 | - if (!toRoute) return; | ||
219 | - const { meta } = toRoute; | ||
220 | - if (meta && meta.affix) { | ||
221 | - return; | 299 | + this.closeMultipleTab({ pathList }); |
222 | } | 300 | } |
223 | - this.commitAddTab((toRoute as unknown) as AppRouteRecordRaw); | 301 | + this.commitCachedMapState(); |
302 | + isGotoPage(); | ||
224 | } | 303 | } |
225 | 304 | ||
226 | @Action | 305 | @Action |
227 | - closeRightTabAction(route: AppRouteRecordRaw | TabItem): void { | 306 | + closeRightTabAction(route: RouteLocationNormalized): void { |
228 | const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath); | 307 | const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath); |
229 | 308 | ||
230 | if (index >= 0 && index < this.tabsState.length - 1) { | 309 | if (index >= 0 && index < this.tabsState.length - 1) { |
231 | const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length); | 310 | const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length); |
232 | 311 | ||
233 | const pathList: string[] = []; | 312 | const pathList: string[] = []; |
234 | - const nameList: string[] = []; | ||
235 | for (const item of rightTabs) { | 313 | for (const item of rightTabs) { |
236 | const affix = item.meta ? item.meta.affix : false; | 314 | const affix = item.meta ? item.meta.affix : false; |
237 | if (!affix) { | 315 | if (!affix) { |
238 | pathList.push(item.fullPath); | 316 | pathList.push(item.fullPath); |
239 | - nameList.push(item.name as string); | ||
240 | } | 317 | } |
241 | } | 318 | } |
242 | - this.closeMultipleTab({ pathList, nameList }); | 319 | + this.closeMultipleTab({ pathList }); |
243 | } | 320 | } |
321 | + this.commitCachedMapState(); | ||
322 | + isGotoPage(); | ||
244 | } | 323 | } |
245 | 324 | ||
246 | @Action | 325 | @Action |
247 | - closeOtherTabAction(route: AppRouteRecordRaw | TabItem): void { | 326 | + closeOtherTabAction(route: RouteLocationNormalized): void { |
248 | const closePathList = this.tabsState.map((item) => item.fullPath); | 327 | const closePathList = this.tabsState.map((item) => item.fullPath); |
249 | const pathList: string[] = []; | 328 | const pathList: string[] = []; |
250 | - const nameList: string[] = []; | ||
251 | closePathList.forEach((path) => { | 329 | closePathList.forEach((path) => { |
252 | if (path !== route.fullPath) { | 330 | if (path !== route.fullPath) { |
253 | const closeItem = this.tabsState.find((item) => item.path === path); | 331 | const closeItem = this.tabsState.find((item) => item.path === path); |
@@ -255,11 +333,12 @@ class Tab extends VuexModule { | @@ -255,11 +333,12 @@ class Tab extends VuexModule { | ||
255 | const affix = closeItem.meta ? closeItem.meta.affix : false; | 333 | const affix = closeItem.meta ? closeItem.meta.affix : false; |
256 | if (!affix) { | 334 | if (!affix) { |
257 | pathList.push(closeItem.fullPath); | 335 | pathList.push(closeItem.fullPath); |
258 | - nameList.push(closeItem.name as string); | ||
259 | } | 336 | } |
260 | } | 337 | } |
261 | }); | 338 | }); |
262 | - this.closeMultipleTab({ pathList, nameList }); | 339 | + this.closeMultipleTab({ pathList }); |
340 | + this.commitCachedMapState(); | ||
341 | + isGotoPage(); | ||
263 | } | 342 | } |
264 | } | 343 | } |
265 | export const tabStore = getModule<Tab>(Tab); | 344 | export const tabStore = getModule<Tab>(Tab); |
src/utils/helper/dynamicImport.ts deleted
100644 → 0
src/utils/helper/routeHelper.ts deleted
100644 → 0
1 | -import type { AppRouteModule, AppRouteRecordRaw, RouteModule } from '/@/router/types'; | ||
2 | -import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'; | ||
3 | -import { createRouter, createWebHashHistory } from 'vue-router'; | ||
4 | - | ||
5 | -import { appStore } from '/@/store/modules/app'; | ||
6 | -import { tabStore } from '/@/store/modules/tab'; | ||
7 | -import { toRaw } from 'vue'; | ||
8 | -import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; | ||
9 | -// import { isDevMode } from '/@/utils/env'; | ||
10 | -import dynamicImport from './dynamicImport'; | ||
11 | -import { omit } from 'lodash-es'; | ||
12 | - | ||
13 | -let currentTo: RouteLocationNormalized | null = null; | ||
14 | - | ||
15 | -export function getCurrentTo() { | ||
16 | - return currentTo; | ||
17 | -} | ||
18 | - | ||
19 | -export function setCurrentTo(to: RouteLocationNormalized) { | ||
20 | - currentTo = to; | ||
21 | -} | ||
22 | -// 转化路由模块 | ||
23 | -// 将多级转成2层。keepAlive问题 | ||
24 | -export function genRouteModule(moduleList: AppRouteModule[] | AppRouteRecordRaw[]) { | ||
25 | - const ret: AppRouteRecordRaw[] = []; | ||
26 | - for (const routeMod of moduleList) { | ||
27 | - let routes: RouteRecordRaw[] = []; | ||
28 | - let layout: AppRouteRecordRaw | undefined; | ||
29 | - if (Reflect.has(routeMod, 'routes')) { | ||
30 | - routes = (routeMod as RouteModule).routes as any; | ||
31 | - layout = (routeMod as RouteModule).layout; | ||
32 | - } else if (Reflect.has(routeMod, 'path')) { | ||
33 | - layout = omit(routeMod, 'children') as any; | ||
34 | - routes = (routeMod.children as RouteRecordRaw[]) || ([] as RouteRecordRaw[]); | ||
35 | - } | ||
36 | - | ||
37 | - const router = createRouter({ routes, history: createWebHashHistory() }); | ||
38 | - | ||
39 | - const flatList = (toRaw(router.getRoutes()).filter( | ||
40 | - (item) => item.children.length === 0 | ||
41 | - ) as unknown) as AppRouteRecordRaw[]; | ||
42 | - flatList.forEach((item) => { | ||
43 | - item.path = `${layout ? layout.path : ''}${item.path}`; | ||
44 | - }); | ||
45 | - if (layout) { | ||
46 | - layout.children = flatList; | ||
47 | - ret.push(layout); | ||
48 | - } else { | ||
49 | - ret.push(...flatList); | ||
50 | - } | ||
51 | - } | ||
52 | - return ret as RouteRecordRaw[]; | ||
53 | -} | ||
54 | - | ||
55 | -// 动态引入 | ||
56 | -function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { | ||
57 | - if (!routes) return; | ||
58 | - routes.forEach((item) => { | ||
59 | - const { component } = item; | ||
60 | - const { children } = item; | ||
61 | - if (component) { | ||
62 | - item.component = dynamicImport(component); | ||
63 | - } | ||
64 | - | ||
65 | - children && asyncImportRoute(children); | ||
66 | - }); | ||
67 | -} | ||
68 | - | ||
69 | -function getLayoutComp(comp: string) { | ||
70 | - return comp === 'PAGE_LAYOUT' ? PAGE_LAYOUT_COMPONENT : ''; | ||
71 | -} | ||
72 | - | ||
73 | -// 将后台对象转成路由对象 | ||
74 | -export function transformObjToRoute<T = any>(routeList: AppRouteModule[]): T[] { | ||
75 | - routeList.forEach((route) => { | ||
76 | - asyncImportRoute( | ||
77 | - Reflect.has(route, 'routes') ? (route as RouteModule).routes : route.children || [] | ||
78 | - ); | ||
79 | - if ((route as RouteModule).layout) { | ||
80 | - (route as RouteModule).layout.component = getLayoutComp( | ||
81 | - (route as RouteModule).layout.component | ||
82 | - ); | ||
83 | - } else { | ||
84 | - route.component = getLayoutComp(route.component); | ||
85 | - (route as RouteModule).layout = omit(route, 'children') as any; | ||
86 | - } | ||
87 | - }); | ||
88 | - return (routeList as unknown) as T[]; | ||
89 | -} | ||
90 | - | ||
91 | -// | ||
92 | -export function getIsOpenTab(toPath: string) { | ||
93 | - const { openKeepAlive, multiTabsSetting: { show } = {} } = appStore.getProjectConfig; | ||
94 | - | ||
95 | - if (show && openKeepAlive) { | ||
96 | - const tabList = tabStore.getTabsState; | ||
97 | - return tabList.some((tab) => tab.path === toPath); | ||
98 | - } | ||
99 | - return false; | ||
100 | -} | ||
101 | - | ||
102 | -export function getParams(data: any = {}) { | ||
103 | - const { params = {} } = data; | ||
104 | - let ret = ''; | ||
105 | - Object.keys(params).forEach((key) => { | ||
106 | - const p = params[key]; | ||
107 | - ret += `/${p}`; | ||
108 | - }); | ||
109 | - return ret; | ||
110 | -} |
src/views/demo/feat/copy/index.vue
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | import { useMessage } from '/@/hooks/web/useMessage'; | 15 | import { useMessage } from '/@/hooks/web/useMessage'; |
16 | 16 | ||
17 | export default defineComponent({ | 17 | export default defineComponent({ |
18 | + name: 'Copy', | ||
18 | components: { CollapseContainer }, | 19 | components: { CollapseContainer }, |
19 | setup() { | 20 | setup() { |
20 | const valueRef = ref(''); | 21 | const valueRef = ref(''); |
src/views/demo/level/Menu111.vue
0 → 100644
src/views/demo/level/Menu12.vue
0 → 100644
src/views/demo/level/Menu2.vue
0 → 100644
src/views/sys/redirect/index.vue
1 | +<template> | ||
2 | + <div /> | ||
3 | +</template> | ||
1 | <script lang="ts"> | 4 | <script lang="ts"> |
2 | import { defineComponent, unref } from 'vue'; | 5 | import { defineComponent, unref } from 'vue'; |
3 | 6 | ||
@@ -18,12 +21,13 @@ | @@ -18,12 +21,13 @@ | ||
18 | path: '/' + _path, | 21 | path: '/' + _path, |
19 | query, | 22 | query, |
20 | }); | 23 | }); |
24 | + // close loading | ||
21 | if (unref(getEnableTransition) && unref(getOpenPageLoading)) { | 25 | if (unref(getEnableTransition) && unref(getOpenPageLoading)) { |
22 | setTimeout(() => { | 26 | setTimeout(() => { |
23 | appStore.setPageLoadingAction(false); | 27 | appStore.setPageLoadingAction(false); |
24 | }, 0); | 28 | }, 0); |
25 | } | 29 | } |
26 | - return () => null; | 30 | + return {}; |
27 | }, | 31 | }, |
28 | }); | 32 | }); |
29 | </script> | 33 | </script> |
yarn.lock
@@ -1061,10 +1061,10 @@ | @@ -1061,10 +1061,10 @@ | ||
1061 | resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.0-rc.2.tgz#c4a95ddc06ca9b9496df03604e66fdefb39f4c4b" | 1061 | resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.0-rc.2.tgz#c4a95ddc06ca9b9496df03604e66fdefb39f4c4b" |
1062 | integrity sha512-BybEHU5/I9EQ0CcwKAqmreZ2bMnAXrqLCTptAc6vPetHMbrXdZfejP5mt57e/8PNSt/qE7BHniU5PCYA+PGIHw== | 1062 | integrity sha512-BybEHU5/I9EQ0CcwKAqmreZ2bMnAXrqLCTptAc6vPetHMbrXdZfejP5mt57e/8PNSt/qE7BHniU5PCYA+PGIHw== |
1063 | 1063 | ||
1064 | -"@iconify/json@^1.1.266": | ||
1065 | - version "1.1.266" | ||
1066 | - resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.266.tgz#3537de808399652b3ca2c89a561216324121b785" | ||
1067 | - integrity sha512-I8S9lChQATaRroMGccdOQkFbBtMt4C2V/PQGiSjDq9yzdyqDCrPNN9X1qM4FoQt84zfW/+JMHIgShi42E+SXeA== | 1064 | +"@iconify/json@^1.1.267": |
1065 | + version "1.1.267" | ||
1066 | + resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.267.tgz#52ab5390fcaf95e0d68260523a3a3fbc575dfe01" | ||
1067 | + integrity sha512-VKNvyALvbuwsXO7r2XvdoqdctmvJzp1/XYOXRfhJ4w+sjtWYp8T3oRGDJ0AZTafzGiBBUaMwCZVP+j87rqgD3w== | ||
1068 | 1068 | ||
1069 | "@koa/cors@^3.1.0": | 1069 | "@koa/cors@^3.1.0": |
1070 | version "3.1.0" | 1070 | version "3.1.0" |
@@ -1535,10 +1535,10 @@ | @@ -1535,10 +1535,10 @@ | ||
1535 | resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" | 1535 | resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" |
1536 | integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== | 1536 | integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== |
1537 | 1537 | ||
1538 | -"@types/yargs@^15.0.10": | ||
1539 | - version "15.0.10" | ||
1540 | - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.10.tgz#0fe3c8173a0d5c3e780b389050140c3f5ea6ea74" | ||
1541 | - integrity sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ== | 1538 | +"@types/yargs@^15.0.11": |
1539 | + version "15.0.11" | ||
1540 | + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.11.tgz#361d7579ecdac1527687bcebf9946621c12ab78c" | ||
1541 | + integrity sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA== | ||
1542 | dependencies: | 1542 | dependencies: |
1543 | "@types/yargs-parser" "*" | 1543 | "@types/yargs-parser" "*" |
1544 | 1544 | ||
@@ -1644,6 +1644,17 @@ | @@ -1644,6 +1644,17 @@ | ||
1644 | estree-walker "^2.0.1" | 1644 | estree-walker "^2.0.1" |
1645 | source-map "^0.6.1" | 1645 | source-map "^0.6.1" |
1646 | 1646 | ||
1647 | +"@vue/compiler-core@3.0.4": | ||
1648 | + version "3.0.4" | ||
1649 | + resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.4.tgz#0122aca6eada4cb28b39ed930af917444755e330" | ||
1650 | + integrity sha512-snpMICsbWTZqBFnPB03qr4DtiSxVYfDF3DvbDSkN9Z9NTM8Chl8E/lYhKBSsvauq91DAWAh8PU3lr9vrLyQsug== | ||
1651 | + dependencies: | ||
1652 | + "@babel/parser" "^7.12.0" | ||
1653 | + "@babel/types" "^7.12.0" | ||
1654 | + "@vue/shared" "3.0.4" | ||
1655 | + estree-walker "^2.0.1" | ||
1656 | + source-map "^0.6.1" | ||
1657 | + | ||
1647 | "@vue/compiler-dom@3.0.2": | 1658 | "@vue/compiler-dom@3.0.2": |
1648 | version "3.0.2" | 1659 | version "3.0.2" |
1649 | resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.2.tgz#1d40de04bcdf9aabb79fb6a802dd70a2f3c2992a" | 1660 | resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.2.tgz#1d40de04bcdf9aabb79fb6a802dd70a2f3c2992a" |
@@ -1660,6 +1671,14 @@ | @@ -1660,6 +1671,14 @@ | ||
1660 | "@vue/compiler-core" "3.0.3" | 1671 | "@vue/compiler-core" "3.0.3" |
1661 | "@vue/shared" "3.0.3" | 1672 | "@vue/shared" "3.0.3" |
1662 | 1673 | ||
1674 | +"@vue/compiler-dom@3.0.4": | ||
1675 | + version "3.0.4" | ||
1676 | + resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.4.tgz#834fd4b15c5698cf9f4505c2bfbccca058a843eb" | ||
1677 | + integrity sha512-FOxbHBIkkGjYQeTz1DlXQjS1Ms8EPXQWsdTdTPeohoS0KzCz6RiOjiAG+jLtMi6Nr5GX2h0TlCvcnI8mcsicFQ== | ||
1678 | + dependencies: | ||
1679 | + "@vue/compiler-core" "3.0.4" | ||
1680 | + "@vue/shared" "3.0.4" | ||
1681 | + | ||
1663 | "@vue/compiler-sfc@*", "@vue/compiler-sfc@^3.0.0-rc.5": | 1682 | "@vue/compiler-sfc@*", "@vue/compiler-sfc@^3.0.0-rc.5": |
1664 | version "3.0.2" | 1683 | version "3.0.2" |
1665 | resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.2.tgz#22c70fed72c347a4d5fa2db2e80594b3193dce57" | 1684 | resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.2.tgz#22c70fed72c347a4d5fa2db2e80594b3193dce57" |
@@ -1704,6 +1723,28 @@ | @@ -1704,6 +1723,28 @@ | ||
1704 | postcss-selector-parser "^6.0.4" | 1723 | postcss-selector-parser "^6.0.4" |
1705 | source-map "^0.6.1" | 1724 | source-map "^0.6.1" |
1706 | 1725 | ||
1726 | +"@vue/compiler-sfc@^3.0.4": | ||
1727 | + version "3.0.4" | ||
1728 | + resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.4.tgz#2119fe1e68d2c268aafa20461c82c139a9adf8e0" | ||
1729 | + integrity sha512-brDn6HTuK6R3oBCjtMPPsIpyJEZFinlnxjtBXww/goFJOJBAU9CrsdegwyZItNnixCFUIg4CLv4Nj1Eg/eKlfg== | ||
1730 | + dependencies: | ||
1731 | + "@babel/parser" "^7.12.0" | ||
1732 | + "@babel/types" "^7.12.0" | ||
1733 | + "@vue/compiler-core" "3.0.4" | ||
1734 | + "@vue/compiler-dom" "3.0.4" | ||
1735 | + "@vue/compiler-ssr" "3.0.4" | ||
1736 | + "@vue/shared" "3.0.4" | ||
1737 | + consolidate "^0.16.0" | ||
1738 | + estree-walker "^2.0.1" | ||
1739 | + hash-sum "^2.0.0" | ||
1740 | + lru-cache "^5.1.1" | ||
1741 | + magic-string "^0.25.7" | ||
1742 | + merge-source-map "^1.1.0" | ||
1743 | + postcss "^7.0.32" | ||
1744 | + postcss-modules "^3.2.2" | ||
1745 | + postcss-selector-parser "^6.0.4" | ||
1746 | + source-map "^0.6.1" | ||
1747 | + | ||
1707 | "@vue/compiler-ssr@3.0.2": | 1748 | "@vue/compiler-ssr@3.0.2": |
1708 | version "3.0.2" | 1749 | version "3.0.2" |
1709 | resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.2.tgz#73af4d274a79bfcc72a996a9b45f1072e7deaa26" | 1750 | resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.2.tgz#73af4d274a79bfcc72a996a9b45f1072e7deaa26" |
@@ -1720,6 +1761,14 @@ | @@ -1720,6 +1761,14 @@ | ||
1720 | "@vue/compiler-dom" "3.0.3" | 1761 | "@vue/compiler-dom" "3.0.3" |
1721 | "@vue/shared" "3.0.3" | 1762 | "@vue/shared" "3.0.3" |
1722 | 1763 | ||
1764 | +"@vue/compiler-ssr@3.0.4": | ||
1765 | + version "3.0.4" | ||
1766 | + resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.4.tgz#ccbd1f55734d51d1402fad825ac102002a7a07c7" | ||
1767 | + integrity sha512-4aYWQEL4+LS4+D44K9Z7xMOWMEjBsz4Li9nMcj2rxRQ35ewK6uFPodvs6ORP60iBDSkwUFZoldFlNemQlu1BFw== | ||
1768 | + dependencies: | ||
1769 | + "@vue/compiler-dom" "3.0.4" | ||
1770 | + "@vue/shared" "3.0.4" | ||
1771 | + | ||
1723 | "@vue/reactivity@3.0.2": | 1772 | "@vue/reactivity@3.0.2": |
1724 | version "3.0.2" | 1773 | version "3.0.2" |
1725 | resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.2.tgz#42ed5af6025b494a5e69b05169fcddf04eebfe77" | 1774 | resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.2.tgz#42ed5af6025b494a5e69b05169fcddf04eebfe77" |
@@ -1734,6 +1783,13 @@ | @@ -1734,6 +1783,13 @@ | ||
1734 | dependencies: | 1783 | dependencies: |
1735 | "@vue/shared" "3.0.3" | 1784 | "@vue/shared" "3.0.3" |
1736 | 1785 | ||
1786 | +"@vue/reactivity@3.0.4": | ||
1787 | + version "3.0.4" | ||
1788 | + resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.4.tgz#b6599dd8271a745960a03f05744ccf7991ba5d8d" | ||
1789 | + integrity sha512-AFTABrLhUYZY2on3ea9FxeXal7w3f6qIp9gT+/oG93H7dFTL5LvVnxygCopv7tvkIl/GSGQb/yK1D1gmXx1Pww== | ||
1790 | + dependencies: | ||
1791 | + "@vue/shared" "3.0.4" | ||
1792 | + | ||
1737 | "@vue/runtime-core@3.0.2": | 1793 | "@vue/runtime-core@3.0.2": |
1738 | version "3.0.2" | 1794 | version "3.0.2" |
1739 | resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.2.tgz#d7ed462af1cb0bf9836668e4e6fab3f2f4b1bc00" | 1795 | resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.2.tgz#d7ed462af1cb0bf9836668e4e6fab3f2f4b1bc00" |
@@ -1750,6 +1806,14 @@ | @@ -1750,6 +1806,14 @@ | ||
1750 | "@vue/reactivity" "3.0.3" | 1806 | "@vue/reactivity" "3.0.3" |
1751 | "@vue/shared" "3.0.3" | 1807 | "@vue/shared" "3.0.3" |
1752 | 1808 | ||
1809 | +"@vue/runtime-core@3.0.4": | ||
1810 | + version "3.0.4" | ||
1811 | + resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.4.tgz#a5b9a001560b1fd8c01a43f68b764c555de7836c" | ||
1812 | + integrity sha512-qH9e4kqU7b3u1JewvLmGmoAGY+mnuBqz7aEKb2mhpEgwa1yFv496BRuUfMXXMCix3+TndUVMJ8jt41FSdNppwg== | ||
1813 | + dependencies: | ||
1814 | + "@vue/reactivity" "3.0.4" | ||
1815 | + "@vue/shared" "3.0.4" | ||
1816 | + | ||
1753 | "@vue/runtime-dom@3.0.3": | 1817 | "@vue/runtime-dom@3.0.3": |
1754 | version "3.0.3" | 1818 | version "3.0.3" |
1755 | resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.3.tgz#5e3e5e5418b9defcac988d2be0cf65596fa2cc03" | 1819 | resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.3.tgz#5e3e5e5418b9defcac988d2be0cf65596fa2cc03" |
@@ -1759,6 +1823,15 @@ | @@ -1759,6 +1823,15 @@ | ||
1759 | "@vue/shared" "3.0.3" | 1823 | "@vue/shared" "3.0.3" |
1760 | csstype "^2.6.8" | 1824 | csstype "^2.6.8" |
1761 | 1825 | ||
1826 | +"@vue/runtime-dom@3.0.4": | ||
1827 | + version "3.0.4" | ||
1828 | + resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.4.tgz#6f81aec545f24511d2c28a315aa3391420b69c68" | ||
1829 | + integrity sha512-BGIoiTSESzWUhN0Ofi2X/q+HN8f6IUFmUEyyBGKbmx7DTAJNZhFfjqsepfXQrM5IGeTfJLB1ZEVyroDQJNXq3g== | ||
1830 | + dependencies: | ||
1831 | + "@vue/runtime-core" "3.0.4" | ||
1832 | + "@vue/shared" "3.0.4" | ||
1833 | + csstype "^2.6.8" | ||
1834 | + | ||
1762 | "@vue/runtime-dom@^3.0.0": | 1835 | "@vue/runtime-dom@^3.0.0": |
1763 | version "3.0.2" | 1836 | version "3.0.2" |
1764 | resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.2.tgz#9d166d03225558025d3d80f5039b646e0051b71c" | 1837 | resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.2.tgz#9d166d03225558025d3d80f5039b646e0051b71c" |
@@ -1778,6 +1851,11 @@ | @@ -1778,6 +1851,11 @@ | ||
1778 | resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.3.tgz#ef12ebff93a446df281e8a0fd765b5aea8e7745b" | 1851 | resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.3.tgz#ef12ebff93a446df281e8a0fd765b5aea8e7745b" |
1779 | integrity sha512-yGgkF7u4W0Dmwri9XdeY50kOowN4UIX7aBQ///jbxx37itpzVjK7QzvD3ltQtPfWaJDGBfssGL0wpAgwX9OJpQ== | 1852 | integrity sha512-yGgkF7u4W0Dmwri9XdeY50kOowN4UIX7aBQ///jbxx37itpzVjK7QzvD3ltQtPfWaJDGBfssGL0wpAgwX9OJpQ== |
1780 | 1853 | ||
1854 | +"@vue/shared@3.0.4": | ||
1855 | + version "3.0.4" | ||
1856 | + resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.4.tgz#6dc50f593bdfdeaa6183d1dbc15e2d45e7c6b8b3" | ||
1857 | + integrity sha512-Swfbz31AaMX48CpFl+YmIrqOH9MgJMTrltG9e26A4ZxYx9LjGuMV+41WnxFzS3Bc9nbrc6sDPM37G6nIT8NJSg== | ||
1858 | + | ||
1781 | "@vuedx/analyze@0.2.4-0": | 1859 | "@vuedx/analyze@0.2.4-0": |
1782 | version "0.2.4-0" | 1860 | version "0.2.4-0" |
1783 | resolved "https://registry.npmjs.org/@vuedx/analyze/-/analyze-0.2.4-0.tgz#52766a6dcd2867320409fe517540fd0bf0394d48" | 1861 | resolved "https://registry.npmjs.org/@vuedx/analyze/-/analyze-0.2.4-0.tgz#52766a6dcd2867320409fe517540fd0bf0394d48" |
@@ -3013,10 +3091,10 @@ crc-32@~1.2.0: | @@ -3013,10 +3091,10 @@ crc-32@~1.2.0: | ||
3013 | exit-on-epipe "~1.0.1" | 3091 | exit-on-epipe "~1.0.1" |
3014 | printj "~1.1.0" | 3092 | printj "~1.1.0" |
3015 | 3093 | ||
3016 | -cross-env@^7.0.2: | ||
3017 | - version "7.0.2" | ||
3018 | - resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" | ||
3019 | - integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== | 3094 | +cross-env@^7.0.3: |
3095 | + version "7.0.3" | ||
3096 | + resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" | ||
3097 | + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== | ||
3020 | dependencies: | 3098 | dependencies: |
3021 | cross-spawn "^7.0.1" | 3099 | cross-spawn "^7.0.1" |
3022 | 3100 | ||
@@ -3449,17 +3527,17 @@ es-module-lexer@^0.3.25: | @@ -3449,17 +3527,17 @@ es-module-lexer@^0.3.25: | ||
3449 | resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz#7b507044e97d5b03b01d4392c74ffeb9c177a83b" | 3527 | resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz#7b507044e97d5b03b01d4392c74ffeb9c177a83b" |
3450 | integrity sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA== | 3528 | integrity sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA== |
3451 | 3529 | ||
3452 | -esbuild-register@^1.1.0: | ||
3453 | - version "1.1.0" | ||
3454 | - resolved "https://registry.npmjs.org/esbuild-register/-/esbuild-register-1.1.0.tgz#8ec1fbf6b84f0d7654b87eec04029a383dcb539d" | ||
3455 | - integrity sha512-A+KGHDc7me/ATyNqnVQKsHxt2A/ORVvV2gmukx5ZtVcy5HVf19QBbHdfdP5QHFA8rF/WHmcnDxaxewu+VUvUhQ== | 3530 | +esbuild-register@^1.1.1: |
3531 | + version "1.1.1" | ||
3532 | + resolved "https://registry.npmjs.org/esbuild-register/-/esbuild-register-1.1.1.tgz#7d50e87ac0b9000085d9e6d9a78e4c2223fcce83" | ||
3533 | + integrity sha512-hAPWuaUkPDLXCENc/AigJZaaDCvCkpmghRw8XPyT+rk08JHcIgUrmw1uabbUTfa6B6J9Wo2bFufb01JjbmzcfQ== | ||
3456 | dependencies: | 3534 | dependencies: |
3457 | joycon "^2.2.5" | 3535 | joycon "^2.2.5" |
3458 | pirates "^4.0.1" | 3536 | pirates "^4.0.1" |
3459 | source-map-support "^0.5.19" | 3537 | source-map-support "^0.5.19" |
3460 | strip-json-comments "^3.1.1" | 3538 | strip-json-comments "^3.1.1" |
3461 | 3539 | ||
3462 | -esbuild@^0.7.17, esbuild@^0.7.19: | 3540 | +esbuild@^0.7.19: |
3463 | version "0.7.22" | 3541 | version "0.7.22" |
3464 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.7.22.tgz#9149b903f8128b7c45a754046c24199d76bbe08e" | 3542 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.7.22.tgz#9149b903f8128b7c45a754046c24199d76bbe08e" |
3465 | integrity sha512-B43SYg8LGWYTCv9Gs0RnuLNwjzpuWOoCaZHTWEDEf5AfrnuDMerPVMdCEu7xOdhFvQ+UqfP2MGU9lxEy0JzccA== | 3543 | integrity sha512-B43SYg8LGWYTCv9Gs0RnuLNwjzpuWOoCaZHTWEDEf5AfrnuDMerPVMdCEu7xOdhFvQ+UqfP2MGU9lxEy0JzccA== |
@@ -3469,6 +3547,11 @@ esbuild@^0.8.12: | @@ -3469,6 +3547,11 @@ esbuild@^0.8.12: | ||
3469 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.15.tgz#cbc4d82a7fc4571d455233456e6fba83fd0364f1" | 3547 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.15.tgz#cbc4d82a7fc4571d455233456e6fba83fd0364f1" |
3470 | integrity sha512-mSaLo9t/oYtQE6FRUEdO47Pr8PisSPzHtgr+LcihIcjBEhbYwjT6WLCQ7noDoTBfIatBCw229rtmIwl9u9UQwg== | 3548 | integrity sha512-mSaLo9t/oYtQE6FRUEdO47Pr8PisSPzHtgr+LcihIcjBEhbYwjT6WLCQ7noDoTBfIatBCw229rtmIwl9u9UQwg== |
3471 | 3549 | ||
3550 | +esbuild@^0.8.17: | ||
3551 | + version "0.8.17" | ||
3552 | + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.17.tgz#1c16c6d5988dcfdcf27a7e1612b7fd05e1477c54" | ||
3553 | + integrity sha512-ReHap+Iyn5BQF0B8F3xrLwu+j57ri5uDUw2ej9XTPAuFDebYiWwRzBY4jhF610bklveXLbCGim/8/2wQKQlu1w== | ||
3554 | + | ||
3472 | escalade@^3.1.1: | 3555 | escalade@^3.1.1: |
3473 | version "3.1.1" | 3556 | version "3.1.1" |
3474 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" | 3557 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" |
@@ -3581,13 +3664,13 @@ esm@^3.2.25: | @@ -3581,13 +3664,13 @@ esm@^3.2.25: | ||
3581 | resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" | 3664 | resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" |
3582 | integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== | 3665 | integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== |
3583 | 3666 | ||
3584 | -esno@^0.2.4: | ||
3585 | - version "0.2.4" | ||
3586 | - resolved "https://registry.npmjs.org/esno/-/esno-0.2.4.tgz#b04a368181bc03e5d11d5147106bf0d0ac4f3a48" | ||
3587 | - integrity sha512-XlgsQe2va257kc1xsZg/X22fRyLVRNkCKEXjONoltA7HeXtmhrQ3n19all0eK0X6YRNE8X9qiVyWV0vMLZvY3w== | 3667 | +esno@^0.3.0: |
3668 | + version "0.3.0" | ||
3669 | + resolved "https://registry.npmjs.org/esno/-/esno-0.3.0.tgz#c818996bdaaf2deaf81413d6f45538ffa6e41b42" | ||
3670 | + integrity sha512-4sF/j8jruQv9jScU8tNkgoDFLjyGxTTB8bmjRmWHyNNygra3WS3X0U1Cc7GuOvfSEjn3NDS57P0LRnzgiupKJg== | ||
3588 | dependencies: | 3671 | dependencies: |
3589 | - esbuild "^0.7.17" | ||
3590 | - esbuild-register "^1.1.0" | 3672 | + esbuild "^0.8.17" |
3673 | + esbuild-register "^1.1.1" | ||
3591 | esm "^3.2.25" | 3674 | esm "^3.2.25" |
3592 | 3675 | ||
3593 | espree@^6.2.1: | 3676 | espree@^6.2.1: |
@@ -8335,6 +8418,15 @@ vue@^3.0.3: | @@ -8335,6 +8418,15 @@ vue@^3.0.3: | ||
8335 | "@vue/runtime-dom" "3.0.3" | 8418 | "@vue/runtime-dom" "3.0.3" |
8336 | "@vue/shared" "3.0.3" | 8419 | "@vue/shared" "3.0.3" |
8337 | 8420 | ||
8421 | +vue@^3.0.4: | ||
8422 | + version "3.0.4" | ||
8423 | + resolved "https://registry.npmjs.org/vue/-/vue-3.0.4.tgz#872c65c143f5717bd5387c61613d9f55f4cc0f43" | ||
8424 | + integrity sha512-2o+AiQF8sAupyhbyl3oxVCl3WCwC/n5NI7VMM+gVQ231qvSB8eI7sCBloloqDJK6yA367EEtmRSeSCf4sxCC+A== | ||
8425 | + dependencies: | ||
8426 | + "@vue/compiler-dom" "3.0.4" | ||
8427 | + "@vue/runtime-dom" "3.0.4" | ||
8428 | + "@vue/shared" "3.0.4" | ||
8429 | + | ||
8338 | vuex-module-decorators@^1.0.1: | 8430 | vuex-module-decorators@^1.0.1: |
8339 | version "1.0.1" | 8431 | version "1.0.1" |
8340 | resolved "https://registry.npmjs.org/vuex-module-decorators/-/vuex-module-decorators-1.0.1.tgz#d34dafb5428a3636f1c26d3d014c15fc9659ccd0" | 8432 | resolved "https://registry.npmjs.org/vuex-module-decorators/-/vuex-module-decorators-1.0.1.tgz#d34dafb5428a3636f1c26d3d014c15fc9659ccd0" |