Browse Source

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>
Haceral 3 years ago
parent
commit
052eff91c4

+ 1 - 0
src/locales/lang/en/layout.ts

@@ -84,6 +84,7 @@ export default {
     breadcrumb: 'Breadcrumbs',
     breadcrumbIcon: 'Breadcrumbs Icon',
     tabs: 'Tabs',
+    tabDetail: 'Tab Detail',
     tabsQuickBtn: 'Tabs quick button',
     tabsRedoBtn: 'Tabs redo button',
     tabsFoldBtn: 'Tabs flod button',

+ 1 - 0
src/locales/lang/en/routes/demo.ts

@@ -67,6 +67,7 @@ export default {
     feat: 'Page Function',
     icon: 'Icon',
     tabs: 'Tabs',
+    tabDetail: 'Tab Detail',
     sessionTimeout: 'Session Timeout',
     print: 'Print',
     contextMenu: 'Context Menu',

+ 1 - 0
src/locales/lang/zh-CN/layout.ts

@@ -84,6 +84,7 @@ export default {
     breadcrumb: '面包屑',
     breadcrumbIcon: '面包屑图标',
     tabs: '标签页',
+    tabDetail: '标签详情页',
     tabsQuickBtn: '标签页快捷按钮',
     tabsRedoBtn: '标签页刷新按钮',
     tabsFoldBtn: '标签页折叠按钮',

+ 1 - 0
src/locales/lang/zh-CN/routes/demo.ts

@@ -67,6 +67,7 @@ export default {
     icon: '图标',
     sessionTimeout: '登录过期',
     tabs: '标签页操作',
+    tabDetail: '标签详情页',
     print: '打印',
     contextMenu: '右键菜单',
     download: '文件下载',

+ 15 - 0
src/router/routes/modules/demo/feat.ts

@@ -53,7 +53,22 @@ const feat: AppRouteModule = {
       component: () => import('/@/views/demo/feat/tabs/index.vue'),
       meta: {
         title: t('routes.demo.feat.tabs'),
+        hideChildrenInMenu: true,
       },
+      children: [
+        {
+          path: 'detail/:id',
+          name: 'TabDetail',
+          component: () => import('/@/views/demo/feat/tabs/TabDetail.vue'),
+          meta: {
+            currentActiveMenu: '/feat/tabs',
+            title: t('routes.demo.feat.tabDetail'),
+            hideMenu: true,
+            dynamicLevel: 3,
+            realPath: '/feat/tabs/detail',
+          },
+        },
+      ],
     },
     {
       path: 'breadcrumb',

+ 4 - 3
src/store/modules/multipleTab.ts

@@ -149,7 +149,7 @@ export const useMultipleTabStore = defineStore({
         this.tabList.splice(updateIndex, 1, curTab);
       } else {
         // Add tab
-        // 获取动态路由层级
+        // 获取动态路由打开数,超过 0 即代表需要控制打开数
         const dynamicLevel = meta?.dynamicLevel ?? -1;
         if (dynamicLevel > 0) {
           // 如果动态路由层级大于 0 了,那么就要限制该路由的打开数限制了
@@ -157,8 +157,9 @@ export const useMultipleTabStore = defineStore({
           // const realName: string = path.match(/(\S*)\//)![1];
           const realPath = meta?.realPath ?? '';
           // 获取到已经打开的动态路由数, 判断是否大于某一个值
-          // 这里先固定为 每个动态路由最大能打开【5】个Tab
-          if (this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= 5) {
+          if (
+            this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= dynamicLevel
+          ) {
             // 关闭第一个
             const index = this.tabList.findIndex((item) => item.meta.realPath === realPath);
             index !== -1 && this.tabList.splice(index, 1);

+ 28 - 0
src/views/demo/feat/tabs/TabDetail.vue

@@ -0,0 +1,28 @@
+<template>
+  <PageWrapper title="Tab详情页面">
+    <div>{{ index }} - 详情页内容在此</div>
+  </PageWrapper>
+</template>
+
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { PageWrapper } from '/@/components/Page';
+  import { useTabs } from '/@/hooks/web/useTabs';
+  import { useRoute } from 'vue-router';
+
+  export default defineComponent({
+    name: 'TabDetail',
+    components: { PageWrapper },
+    setup() {
+      const route = useRoute();
+      const index = route.params?.id ?? -1;
+      const { setTitle } = useTabs();
+
+      // 设置标识
+      setTitle(`No.${index} - 详情信息`);
+      return {
+        index,
+      };
+    },
+  });
+</script>

+ 14 - 1
src/views/demo/feat/tabs/index.vue

@@ -16,20 +16,28 @@
       <a-button class="mr-2" @click="closeCurrent"> 关闭当前 </a-button>
       <a-button class="mr-2" @click="refreshPage"> 刷新当前 </a-button>
     </CollapseContainer>
+
+    <CollapseContainer class="mt-4" title="标签页复用超出限制自动关闭(使用场景: 动态路由)">
+      <a-button v-for="index in 6" :key="index" class="mr-2" @click="toDetail(index)">
+        打开{{ index }}详情页
+      </a-button>
+    </CollapseContainer>
   </PageWrapper>
 </template>
 <script lang="ts">
   import { defineComponent, ref } from 'vue';
-  import { CollapseContainer } from '/@/components/Container/index';
+  import { CollapseContainer } from '/@/components/Container';
   import { useTabs } from '/@/hooks/web/useTabs';
   import { PageWrapper } from '/@/components/Page';
   import { Input, Alert } from 'ant-design-vue';
   import { useMessage } from '/@/hooks/web/useMessage';
+  import { useGo } from '/@/hooks/web/usePage';
 
   export default defineComponent({
     name: 'TabsDemo',
     components: { CollapseContainer, PageWrapper, [Input.name]: Input, [Alert.name]: Alert },
     setup() {
+      const go = useGo();
       const title = ref<string>('');
       const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage, setTitle } =
         useTabs();
@@ -41,12 +49,17 @@
           createMessage.error('请输入要设置的Tab标题!');
         }
       }
+
+      function toDetail(index: number) {
+        go(`/feat/tabs/detail/${index}`);
+      }
       return {
         closeAll,
         closeLeft,
         closeRight,
         closeOther,
         closeCurrent,
+        toDetail,
         refreshPage,
         setTabTitle,
         title,