useMultipleTabs.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { toRaw, ref, nextTick } from 'vue';
  2. import type { RouteLocationNormalized } from 'vue-router';
  3. import { useDesign } from '/@/hooks/web/useDesign';
  4. import { useSortable } from '/@/hooks/web/useSortable';
  5. import { useMultipleTabStore } from '/@/store/modules/multipleTab';
  6. import { isNullAndUnDef } from '/@/utils/is';
  7. import projectSetting from '/@/settings/projectSetting';
  8. import { useRouter } from 'vue-router';
  9. import { useI18n } from '/@/hooks/web/useI18n';
  10. const { t } = useI18n();
  11. export function initAffixTabs(): string[] {
  12. const affixList = ref<RouteLocationNormalized[]>([]);
  13. const tabStore = useMultipleTabStore();
  14. const router = useRouter();
  15. /**
  16. * @description: Filter all fixed routes
  17. */
  18. function filterAffixTabs(routes: RouteLocationNormalized[]) {
  19. const tabs: RouteLocationNormalized[] = [];
  20. routes &&
  21. routes.forEach((route) => {
  22. if (route.meta && route.meta.affix) {
  23. tabs.push(toRaw(route));
  24. }
  25. });
  26. return tabs;
  27. }
  28. /**
  29. * @description: Set fixed tabs
  30. */
  31. function addAffixTabs(): void {
  32. const affixTabs = filterAffixTabs(router.getRoutes() as unknown as RouteLocationNormalized[]);
  33. affixList.value = affixTabs;
  34. for (const tab of affixTabs) {
  35. tabStore.addTab({
  36. meta: tab.meta,
  37. name: tab.name,
  38. path: tab.path,
  39. } as unknown as RouteLocationNormalized);
  40. }
  41. }
  42. let isAddAffix = false;
  43. if (!isAddAffix) {
  44. addAffixTabs();
  45. isAddAffix = true;
  46. }
  47. return affixList.value.map((item) => item.meta?.title).filter(Boolean) as string[];
  48. }
  49. export function useTabsDrag(affixTextList: string[]) {
  50. const tabStore = useMultipleTabStore();
  51. const { multiTabsSetting } = projectSetting;
  52. const { prefixCls } = useDesign('multiple-tabs');
  53. nextTick(() => {
  54. if (!multiTabsSetting.canDrag) return;
  55. const el = document.querySelectorAll(
  56. `.${prefixCls} .ant-tabs-nav-wrap > div`,
  57. )?.[0] as HTMLElement;
  58. const { initSortable } = useSortable(el, {
  59. filter: (_evt, target: HTMLElement) => {
  60. const text = target.innerText;
  61. if (!text) return false;
  62. return affixTextList.map((res) => t(res)).includes(text);
  63. },
  64. onEnd: (evt) => {
  65. const { oldIndex, newIndex } = evt;
  66. if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
  67. return;
  68. }
  69. tabStore.sortTabs(oldIndex, newIndex);
  70. },
  71. });
  72. initSortable();
  73. });
  74. }