index.tsx 4.7 KB

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