use-tabs.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import type { ComputedRef } from 'vue';
  2. import type { RouteLocationNormalized } from 'vue-router';
  3. import { useRoute, useRouter } from 'vue-router';
  4. import { useTabbarStore } from '@vben/stores';
  5. export function useTabs() {
  6. const router = useRouter();
  7. const route = useRoute();
  8. const tabbarStore = useTabbarStore();
  9. async function closeLeftTabs(tab?: RouteLocationNormalized) {
  10. await tabbarStore.closeLeftTabs(tab || route);
  11. }
  12. async function closeAllTabs() {
  13. await tabbarStore.closeAllTabs(router);
  14. }
  15. async function closeRightTabs(tab?: RouteLocationNormalized) {
  16. await tabbarStore.closeRightTabs(tab || route);
  17. }
  18. async function closeOtherTabs(tab?: RouteLocationNormalized) {
  19. await tabbarStore.closeOtherTabs(tab || route);
  20. }
  21. async function closeCurrentTab(tab?: RouteLocationNormalized) {
  22. await tabbarStore.closeTab(tab || route, router);
  23. }
  24. async function pinTab(tab?: RouteLocationNormalized) {
  25. await tabbarStore.pinTab(tab || route);
  26. }
  27. async function unpinTab(tab?: RouteLocationNormalized) {
  28. await tabbarStore.unpinTab(tab || route);
  29. }
  30. async function toggleTabPin(tab?: RouteLocationNormalized) {
  31. await tabbarStore.toggleTabPin(tab || route);
  32. }
  33. async function refreshTab(name?: string) {
  34. await tabbarStore.refresh(name || router);
  35. }
  36. async function openTabInNewWindow(tab?: RouteLocationNormalized) {
  37. await tabbarStore.openTabInNewWindow(tab || route);
  38. }
  39. async function closeTabByKey(key: string) {
  40. await tabbarStore.closeTabByKey(key, router);
  41. }
  42. /**
  43. * 设置当前标签页的标题
  44. *
  45. * @description 支持设置静态标题字符串或动态计算标题
  46. * @description 动态标题会在每次渲染时重新计算,适用于多语言或状态相关的标题
  47. *
  48. * @param title - 标题内容
  49. * - 静态标题: 直接传入字符串
  50. * - 动态标题: 传入 ComputedRef
  51. *
  52. * @example
  53. * // 静态标题
  54. * setTabTitle('标签页')
  55. *
  56. * // 动态标题(多语言)
  57. * setTabTitle(computed(() => t('page.title')))
  58. */
  59. async function setTabTitle(title: ComputedRef<string> | string) {
  60. tabbarStore.setUpdateTime();
  61. await tabbarStore.setTabTitle(route, title);
  62. }
  63. async function resetTabTitle() {
  64. tabbarStore.setUpdateTime();
  65. await tabbarStore.resetTabTitle(route);
  66. }
  67. /**
  68. * 获取操作是否禁用
  69. * @param tab
  70. */
  71. function getTabDisableState(tab: RouteLocationNormalized = route) {
  72. const tabs = tabbarStore.getTabs;
  73. const affixTabs = tabbarStore.affixTabs;
  74. const index = tabs.findIndex((item) => item.path === tab.path);
  75. const disabled = tabs.length <= 1;
  76. const { meta } = tab;
  77. const affixTab = meta?.affixTab ?? false;
  78. const isCurrentTab = route.path === tab.path;
  79. // 当前处于最左侧或者减去固定标签页的数量等于0
  80. const disabledCloseLeft =
  81. index === 0 || index - affixTabs.length <= 0 || !isCurrentTab;
  82. const disabledCloseRight = !isCurrentTab || index === tabs.length - 1;
  83. const disabledCloseOther =
  84. disabled || !isCurrentTab || tabs.length - affixTabs.length <= 1;
  85. return {
  86. disabledCloseAll: disabled,
  87. disabledCloseCurrent: !!affixTab || disabled,
  88. disabledCloseLeft,
  89. disabledCloseOther,
  90. disabledCloseRight,
  91. disabledRefresh: !isCurrentTab,
  92. };
  93. }
  94. return {
  95. closeAllTabs,
  96. closeCurrentTab,
  97. closeLeftTabs,
  98. closeOtherTabs,
  99. closeRightTabs,
  100. closeTabByKey,
  101. getTabDisableState,
  102. openTabInNewWindow,
  103. pinTab,
  104. refreshTab,
  105. resetTabTitle,
  106. setTabTitle,
  107. toggleTabPin,
  108. unpinTab,
  109. };
  110. }