Commit 052eff91c4b63f4c9e08b80ae171e96d656ec607
Committed by
GitHub
1 parent
e1cbe23e
perf: Improve the dynamic routing and automatically close the Tab function (#1264)
* 增加动态路由最大打开Tab数控制 * 增加动态路由打开数控制Router参数 * feat(Tab): 新增动态路由打开数限制Demo * fix(multipleTab.ts): 将原来的打开数限制从固定的 5 修改为读取配置 Co-authored-by: Haceral <18274416193@163.com>
Showing
8 changed files
with
65 additions
and
4 deletions
src/locales/lang/en/layout.ts
src/locales/lang/en/routes/demo.ts
src/locales/lang/zh-CN/layout.ts
src/locales/lang/zh-CN/routes/demo.ts
src/router/routes/modules/demo/feat.ts
... | ... | @@ -53,7 +53,22 @@ const feat: AppRouteModule = { |
53 | 53 | component: () => import('/@/views/demo/feat/tabs/index.vue'), |
54 | 54 | meta: { |
55 | 55 | title: t('routes.demo.feat.tabs'), |
56 | + hideChildrenInMenu: true, | |
56 | 57 | }, |
58 | + children: [ | |
59 | + { | |
60 | + path: 'detail/:id', | |
61 | + name: 'TabDetail', | |
62 | + component: () => import('/@/views/demo/feat/tabs/TabDetail.vue'), | |
63 | + meta: { | |
64 | + currentActiveMenu: '/feat/tabs', | |
65 | + title: t('routes.demo.feat.tabDetail'), | |
66 | + hideMenu: true, | |
67 | + dynamicLevel: 3, | |
68 | + realPath: '/feat/tabs/detail', | |
69 | + }, | |
70 | + }, | |
71 | + ], | |
57 | 72 | }, |
58 | 73 | { |
59 | 74 | path: 'breadcrumb', | ... | ... |
src/store/modules/multipleTab.ts
... | ... | @@ -149,7 +149,7 @@ export const useMultipleTabStore = defineStore({ |
149 | 149 | this.tabList.splice(updateIndex, 1, curTab); |
150 | 150 | } else { |
151 | 151 | // Add tab |
152 | - // 获取动态路由层级 | |
152 | + // 获取动态路由打开数,超过 0 即代表需要控制打开数 | |
153 | 153 | const dynamicLevel = meta?.dynamicLevel ?? -1; |
154 | 154 | if (dynamicLevel > 0) { |
155 | 155 | // 如果动态路由层级大于 0 了,那么就要限制该路由的打开数限制了 |
... | ... | @@ -157,8 +157,9 @@ export const useMultipleTabStore = defineStore({ |
157 | 157 | // const realName: string = path.match(/(\S*)\//)![1]; |
158 | 158 | const realPath = meta?.realPath ?? ''; |
159 | 159 | // 获取到已经打开的动态路由数, 判断是否大于某一个值 |
160 | - // 这里先固定为 每个动态路由最大能打开【5】个Tab | |
161 | - if (this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= 5) { | |
160 | + if ( | |
161 | + this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= dynamicLevel | |
162 | + ) { | |
162 | 163 | // 关闭第一个 |
163 | 164 | const index = this.tabList.findIndex((item) => item.meta.realPath === realPath); |
164 | 165 | index !== -1 && this.tabList.splice(index, 1); | ... | ... |
src/views/demo/feat/tabs/TabDetail.vue
0 → 100644
1 | +<template> | |
2 | + <PageWrapper title="Tab详情页面"> | |
3 | + <div>{{ index }} - 详情页内容在此</div> | |
4 | + </PageWrapper> | |
5 | +</template> | |
6 | + | |
7 | +<script lang="ts"> | |
8 | + import { defineComponent } from 'vue'; | |
9 | + import { PageWrapper } from '/@/components/Page'; | |
10 | + import { useTabs } from '/@/hooks/web/useTabs'; | |
11 | + import { useRoute } from 'vue-router'; | |
12 | + | |
13 | + export default defineComponent({ | |
14 | + name: 'TabDetail', | |
15 | + components: { PageWrapper }, | |
16 | + setup() { | |
17 | + const route = useRoute(); | |
18 | + const index = route.params?.id ?? -1; | |
19 | + const { setTitle } = useTabs(); | |
20 | + | |
21 | + // 设置标识 | |
22 | + setTitle(`No.${index} - 详情信息`); | |
23 | + return { | |
24 | + index, | |
25 | + }; | |
26 | + }, | |
27 | + }); | |
28 | +</script> | ... | ... |
src/views/demo/feat/tabs/index.vue
... | ... | @@ -16,20 +16,28 @@ |
16 | 16 | <a-button class="mr-2" @click="closeCurrent"> 关闭当前 </a-button> |
17 | 17 | <a-button class="mr-2" @click="refreshPage"> 刷新当前 </a-button> |
18 | 18 | </CollapseContainer> |
19 | + | |
20 | + <CollapseContainer class="mt-4" title="标签页复用超出限制自动关闭(使用场景: 动态路由)"> | |
21 | + <a-button v-for="index in 6" :key="index" class="mr-2" @click="toDetail(index)"> | |
22 | + 打开{{ index }}详情页 | |
23 | + </a-button> | |
24 | + </CollapseContainer> | |
19 | 25 | </PageWrapper> |
20 | 26 | </template> |
21 | 27 | <script lang="ts"> |
22 | 28 | import { defineComponent, ref } from 'vue'; |
23 | - import { CollapseContainer } from '/@/components/Container/index'; | |
29 | + import { CollapseContainer } from '/@/components/Container'; | |
24 | 30 | import { useTabs } from '/@/hooks/web/useTabs'; |
25 | 31 | import { PageWrapper } from '/@/components/Page'; |
26 | 32 | import { Input, Alert } from 'ant-design-vue'; |
27 | 33 | import { useMessage } from '/@/hooks/web/useMessage'; |
34 | + import { useGo } from '/@/hooks/web/usePage'; | |
28 | 35 | |
29 | 36 | export default defineComponent({ |
30 | 37 | name: 'TabsDemo', |
31 | 38 | components: { CollapseContainer, PageWrapper, [Input.name]: Input, [Alert.name]: Alert }, |
32 | 39 | setup() { |
40 | + const go = useGo(); | |
33 | 41 | const title = ref<string>(''); |
34 | 42 | const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage, setTitle } = |
35 | 43 | useTabs(); |
... | ... | @@ -41,12 +49,17 @@ |
41 | 49 | createMessage.error('请输入要设置的Tab标题!'); |
42 | 50 | } |
43 | 51 | } |
52 | + | |
53 | + function toDetail(index: number) { | |
54 | + go(`/feat/tabs/detail/${index}`); | |
55 | + } | |
44 | 56 | return { |
45 | 57 | closeAll, |
46 | 58 | closeLeft, |
47 | 59 | closeRight, |
48 | 60 | closeOther, |
49 | 61 | closeCurrent, |
62 | + toDetail, | |
50 | 63 | refreshPage, |
51 | 64 | setTabTitle, |
52 | 65 | title, | ... | ... |