index.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import type { TabContentProps } from './tab.data';
  2. import type { TabItem } from '/@/store/modules/tab';
  3. import type { AppRouteRecordRaw } from '/@/router/types';
  4. import {
  5. defineComponent,
  6. watch,
  7. computed,
  8. // ref,
  9. unref,
  10. // onMounted,
  11. toRaw,
  12. } from 'vue';
  13. import { Tabs } from 'ant-design-vue';
  14. import TabContent from './TabContent';
  15. import { useGo } from '/@/hooks/web/usePage';
  16. import { TabContentEnum } from './tab.data';
  17. import { useRouter } from 'vue-router';
  18. import { tabStore } from '/@/store/modules/tab';
  19. import { closeTab } from './useTabDropdown';
  20. import router from '/@/router';
  21. import { useTabs } from '/@/hooks/web/useTabs';
  22. // import { PageEnum } from '/@/enums/pageEnum';
  23. import './index.less';
  24. export default defineComponent({
  25. name: 'MultiTabs',
  26. setup() {
  27. let isAddAffix = false;
  28. const go = useGo();
  29. const { currentRoute } = useRouter();
  30. const {
  31. // addTab,
  32. activeKeyRef,
  33. } = useTabs();
  34. // onMounted(() => {
  35. // const route = unref(currentRoute);
  36. // addTab(unref(currentRoute).path as PageEnum, false, {
  37. // query: route.query,
  38. // params: route.params,
  39. // });
  40. // });
  41. // 当前激活tab
  42. // const activeKeyRef = ref<string>('');
  43. // 当前tab列表
  44. const getTabsState = computed(() => {
  45. return tabStore.getTabsState;
  46. });
  47. if (!isAddAffix) {
  48. addAffixTabs();
  49. isAddAffix = true;
  50. }
  51. watch(
  52. () => unref(currentRoute).path,
  53. (path) => {
  54. if (activeKeyRef.value !== path) {
  55. activeKeyRef.value = path;
  56. }
  57. // 监听路由的话虽然可以,但是路由切换的时间会造成卡顿现象?
  58. // 使用useTab的addTab的话,当用户手动调转,需要自行调用addTab
  59. // tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw);
  60. const { affix } = currentRoute.value.meta || {};
  61. if (affix) return;
  62. const hasInTab = tabStore.getTabsState.some(
  63. (item) => item.fullPath === currentRoute.value.fullPath
  64. );
  65. if (!hasInTab) {
  66. tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw);
  67. }
  68. },
  69. {
  70. immediate: true,
  71. }
  72. );
  73. /**
  74. * @description: 过滤所有固定路由
  75. */
  76. function filterAffixTabs(routes: AppRouteRecordRaw[]) {
  77. const tabs: TabItem[] = [];
  78. routes &&
  79. routes.forEach((route) => {
  80. if (route.meta && route.meta.affix) {
  81. tabs.push(toRaw(route) as TabItem);
  82. }
  83. });
  84. return tabs;
  85. }
  86. /**
  87. * @description: 设置固定tabs
  88. */
  89. function addAffixTabs(): void {
  90. const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as AppRouteRecordRaw[]);
  91. for (const tab of affixTabs) {
  92. tabStore.commitAddTab(tab);
  93. }
  94. }
  95. // tab切换
  96. function handleChange(activeKey: any) {
  97. activeKeyRef.value = activeKey;
  98. go(activeKey, false);
  99. }
  100. // 关闭当前ab
  101. function handleEdit(targetKey: string) {
  102. // 新增操作隐藏,目前只使用删除操作
  103. const index = unref(getTabsState).findIndex((item) => item.path === targetKey);
  104. index !== -1 && closeTab(unref(getTabsState)[index]);
  105. }
  106. function renderQuick() {
  107. const tabContentProps: TabContentProps = {
  108. tabItem: (currentRoute as unknown) as AppRouteRecordRaw,
  109. type: TabContentEnum.EXTRA_TYPE,
  110. trigger: ['click', 'contextmenu'],
  111. };
  112. return (
  113. <span>
  114. <TabContent {...(tabContentProps as any)} />
  115. </span>
  116. );
  117. }
  118. function renderTabs() {
  119. return unref(getTabsState).map((item: TabItem) => {
  120. return (
  121. <Tabs.TabPane key={item.path} closable={!(item && item.meta && item.meta.affix)}>
  122. {{
  123. tab: () => <TabContent tabItem={item} />,
  124. }}
  125. </Tabs.TabPane>
  126. );
  127. });
  128. }
  129. return () => {
  130. return (
  131. <div class="multiple-tabs">
  132. <Tabs
  133. type="editable-card"
  134. size="small"
  135. animated={false}
  136. hideAdd={true}
  137. tabBarGutter={2}
  138. activeKey={unref(activeKeyRef)}
  139. onChange={handleChange}
  140. onEdit={handleEdit}
  141. >
  142. {{
  143. default: () => renderTabs(),
  144. tabBarExtraContent: () => renderQuick(),
  145. }}
  146. </Tabs>
  147. </div>
  148. );
  149. };
  150. },
  151. });