useMultipleTabs.ts 2.3 KB

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