index.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 { activeKeyRef } = useTabs();
  32. // 当前tab列表
  33. const getTabsState = computed(() => {
  34. return tabStore.getTabsState;
  35. });
  36. if (!isAddAffix) {
  37. addAffixTabs();
  38. isAddAffix = true;
  39. }
  40. watch(
  41. () => unref(currentRoute).path,
  42. () => {
  43. if (!userStore.getTokenState) return;
  44. const { path: rPath, fullPath } = unref(currentRoute);
  45. if (activeKeyRef.value !== (fullPath || rPath)) {
  46. activeKeyRef.value = fullPath || rPath;
  47. }
  48. tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw);
  49. },
  50. {
  51. immediate: true,
  52. }
  53. );
  54. /**
  55. * @description: 过滤所有固定路由
  56. */
  57. function filterAffixTabs(routes: AppRouteRecordRaw[]) {
  58. const tabs: TabItem[] = [];
  59. routes &&
  60. routes.forEach((route) => {
  61. if (route.meta && route.meta.affix) {
  62. tabs.push(toRaw(route) as TabItem);
  63. }
  64. });
  65. return tabs;
  66. }
  67. /**
  68. * @description: 设置固定tabs
  69. */
  70. function addAffixTabs(): void {
  71. const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as AppRouteRecordRaw[]);
  72. for (const tab of affixTabs) {
  73. tabStore.commitAddTab(tab);
  74. }
  75. }
  76. // tab切换
  77. function handleChange(activeKey: any) {
  78. activeKeyRef.value = activeKey;
  79. go(activeKey, false);
  80. }
  81. // 关闭当前ab
  82. function handleEdit(targetKey: string) {
  83. // 新增操作隐藏,目前只使用删除操作
  84. const index = unref(getTabsState).findIndex(
  85. (item) => (item.fullPath || item.path) === targetKey
  86. );
  87. index !== -1 && closeTab(unref(getTabsState)[index]);
  88. }
  89. function renderQuick() {
  90. const tabContentProps: TabContentProps = {
  91. tabItem: (currentRoute as unknown) as AppRouteRecordRaw,
  92. type: TabContentEnum.EXTRA_TYPE,
  93. trigger: ['click', 'contextmenu'],
  94. };
  95. return (
  96. <span>
  97. <TabContent {...(tabContentProps as any)} />
  98. </span>
  99. );
  100. }
  101. function renderTabs() {
  102. return unref(getTabsState).map((item: TabItem) => {
  103. const key = item.query ? item.fullPath : item.path;
  104. return (
  105. <Tabs.TabPane key={key} closable={!(item && item.meta && item.meta.affix)}>
  106. {{
  107. tab: () => <TabContent tabItem={item} />,
  108. }}
  109. </Tabs.TabPane>
  110. );
  111. });
  112. }
  113. return () => {
  114. return (
  115. <div class="multiple-tabs">
  116. <Tabs
  117. type="editable-card"
  118. size="small"
  119. animated={false}
  120. hideAdd={true}
  121. tabBarGutter={4}
  122. activeKey={unref(activeKeyRef)}
  123. onChange={handleChange}
  124. onEdit={handleEdit}
  125. >
  126. {{
  127. default: () => renderTabs(),
  128. tabBarExtraContent: () => renderQuick(),
  129. }}
  130. </Tabs>
  131. </div>
  132. );
  133. };
  134. },
  135. });