index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <div :class="getWrapClass">
  3. <Tabs
  4. type="editable-card"
  5. size="small"
  6. :animated="false"
  7. :hideAdd="true"
  8. :tabBarGutter="3"
  9. :activeKey="activeKeyRef"
  10. @change="handleChange"
  11. @edit="(e) => handleEdit(`${e}`)"
  12. >
  13. <template v-for="item in getTabsState" :key="item.query ? item.fullPath : item.path">
  14. <TabPane :closable="!(item && item.meta && item.meta.affix)">
  15. <template #tab>
  16. <TabContent :tabItem="item" />
  17. </template>
  18. </TabPane>
  19. </template>
  20. <template #rightExtra v-if="getShowRedo || getShowQuick">
  21. <SettingButton v-if="(getShowFold && getIsUnFold) || !getShowHeader" />
  22. <TabRedo v-if="getShowRedo" />
  23. <TabContent isExtra :tabItem="$route" v-if="getShowQuick" />
  24. <FoldButton v-if="getShowFold" />
  25. </template>
  26. </Tabs>
  27. </div>
  28. </template>
  29. <script lang="ts">
  30. import type { RouteLocationNormalized, RouteMeta } from 'vue-router';
  31. import { defineComponent, computed, unref, ref } from 'vue';
  32. import { Tabs } from 'ant-design-vue';
  33. import TabContent from './components/TabContent.vue';
  34. import FoldButton from './components/FoldButton.vue';
  35. import TabRedo from './components/TabRedo.vue';
  36. import { useGo } from '/@/hooks/web/usePage';
  37. import { useMultipleTabStore } from '/@/store/modules/multipleTab';
  38. import { useUserStore } from '/@/store/modules/user';
  39. import { initAffixTabs, useTabsDrag } from './useMultipleTabs';
  40. import { useDesign } from '/@/hooks/web/useDesign';
  41. import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
  42. import { REDIRECT_NAME } from '/@/router/constant';
  43. import { listenerRouteChange } from '/@/logics/mitt/routeChange';
  44. import { useRouter } from 'vue-router';
  45. import { useMouse } from '@vueuse/core';
  46. import { multipleTabHeight } from '/@/settings/designSetting';
  47. import SettingButton from './components/SettingButton.vue';
  48. import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
  49. import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  50. export default defineComponent({
  51. name: 'MultipleTabs',
  52. components: {
  53. TabRedo,
  54. FoldButton,
  55. Tabs,
  56. TabPane: Tabs.TabPane,
  57. TabContent,
  58. SettingButton,
  59. },
  60. setup() {
  61. const affixTextList = initAffixTabs();
  62. const activeKeyRef = ref('');
  63. useTabsDrag(affixTextList);
  64. const tabStore = useMultipleTabStore();
  65. const userStore = useUserStore();
  66. const router = useRouter();
  67. const { prefixCls } = useDesign('multiple-tabs');
  68. const go = useGo();
  69. const { getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting();
  70. const getTabsState = computed(() => {
  71. return tabStore.getTabList.filter((item) => !item.meta?.hideTab);
  72. });
  73. const unClose = computed(() => unref(getTabsState).length === 1);
  74. const { y: mouseY } = useMouse();
  75. const { getShowMenu } = useMenuSetting();
  76. const { getShowHeader } = useHeaderSetting();
  77. const getIsUnFold = computed(() => !unref(getShowMenu) && !unref(getShowHeader));
  78. const getWrapClass = computed(() => {
  79. return [
  80. prefixCls,
  81. {
  82. [`${prefixCls}--hide-close`]: unref(unClose),
  83. [`${prefixCls}--hover`]: unref(mouseY) < multipleTabHeight,
  84. },
  85. ];
  86. });
  87. listenerRouteChange((route) => {
  88. const { name } = route;
  89. if (name === REDIRECT_NAME || !route || !userStore.getToken) {
  90. return;
  91. }
  92. const { path, fullPath, meta = {} } = route;
  93. const { currentActiveMenu, hideTab } = meta as RouteMeta;
  94. const isHide = !hideTab ? null : currentActiveMenu;
  95. const p = isHide || fullPath || path;
  96. if (activeKeyRef.value !== p) {
  97. activeKeyRef.value = p as string;
  98. }
  99. if (isHide) {
  100. const findParentRoute = router
  101. .getRoutes()
  102. .find((item) => item.path === currentActiveMenu);
  103. findParentRoute && tabStore.addTab(findParentRoute as unknown as RouteLocationNormalized);
  104. } else {
  105. tabStore.addTab(unref(route));
  106. }
  107. });
  108. function handleChange(activeKey: any) {
  109. activeKeyRef.value = activeKey;
  110. go(activeKey, false);
  111. }
  112. // Close the current tab
  113. function handleEdit(targetKey: string) {
  114. // Added operation to hide, currently only use delete operation
  115. if (unref(unClose)) {
  116. return;
  117. }
  118. tabStore.closeTabByKey(targetKey, router);
  119. }
  120. return {
  121. getWrapClass,
  122. handleEdit,
  123. handleChange,
  124. activeKeyRef,
  125. getTabsState,
  126. getShowQuick,
  127. getShowRedo,
  128. getShowFold,
  129. getIsUnFold,
  130. getShowHeader,
  131. };
  132. },
  133. });
  134. </script>
  135. <style lang="less">
  136. @import url('./index.less');
  137. </style>