admin-vben5/packages/effects/layouts/src/basic/tabbar/use-tabbar.ts

223 lines
5.3 KiB
TypeScript
Raw Normal View History

import type { RouteLocationNormalizedGeneric } from 'vue-router';
import type { TabDefinition } from '@vben/types';
2024-05-19 21:20:42 +08:00
import type { IContextMenuItem } from '@vben-core/tabs-ui';
import { computed, ref, watch } from 'vue';
2024-06-08 19:49:06 +08:00
import { useRoute, useRouter } from 'vue-router';
import { useContentMaximize, useTabs } from '@vben/hooks';
2024-05-19 21:20:42 +08:00
import {
ArrowLeftToLine,
ArrowRightLeft,
ArrowRightToLine,
ExternalLink,
FoldHorizontal,
Fullscreen,
Minimize2,
Pin,
PinOff,
RotateCw,
X,
} from '@vben/icons';
import { $t, useI18n } from '@vben/locales';
2024-07-30 21:10:28 +08:00
import { useAccessStore, useTabbarStore } from '@vben/stores';
import { filterTree } from '@vben/utils';
export function useTabbar() {
2024-05-19 21:20:42 +08:00
const router = useRouter();
const route = useRoute();
2024-07-30 21:10:28 +08:00
const accessStore = useAccessStore();
const tabbarStore = useTabbarStore();
const { contentIsMaximize, toggleMaximize } = useContentMaximize();
const {
closeAllTabs,
closeCurrentTab,
closeLeftTabs,
closeOtherTabs,
closeRightTabs,
closeTabByKey,
getTabDisableState,
openTabInNewWindow,
refreshTab,
toggleTabPin,
} = useTabs();
2024-05-19 21:20:42 +08:00
const currentActive = computed(() => {
return route.fullPath;
2024-05-19 21:20:42 +08:00
});
const { locale } = useI18n();
const currentTabs = ref<RouteLocationNormalizedGeneric[]>();
2024-07-20 09:36:10 +08:00
watch(
[
2024-07-30 21:10:28 +08:00
() => tabbarStore.getTabs,
() => tabbarStore.updateTime,
2024-07-20 09:36:10 +08:00
() => locale.value,
],
([tabs]) => {
currentTabs.value = tabs.map((item) => wrapperTabLocale(item));
},
);
2024-05-19 21:20:42 +08:00
/**
*
*/
const initAffixTabs = () => {
const affixTabs = filterTree(router.getRoutes(), (route) => {
return !!route.meta?.affixTab;
});
2024-07-30 21:10:28 +08:00
tabbarStore.setAffixTabs(affixTabs);
2024-05-19 21:20:42 +08:00
};
// 点击tab,跳转路由
const handleClick = (key: string) => {
router.push(key);
};
// 关闭tab
const handleClose = async (key: string) => {
await closeTabByKey(key);
2024-05-19 21:20:42 +08:00
};
function wrapperTabLocale(tab: RouteLocationNormalizedGeneric) {
return {
...tab,
meta: {
...tab?.meta,
title: $t(tab?.meta?.title as string),
},
};
}
2024-05-19 21:20:42 +08:00
watch(
2024-07-30 21:10:28 +08:00
() => accessStore.accessMenus,
2024-05-19 21:20:42 +08:00
() => {
initAffixTabs();
},
{ immediate: true },
);
watch(
() => route.path,
() => {
const meta = route.matched?.[route.matched.length - 1]?.meta;
tabbarStore.addTab({
...route,
meta: meta || route.meta,
});
2024-05-19 21:20:42 +08:00
},
{ immediate: true },
);
const createContextMenus = (tab: TabDefinition) => {
const {
disabledCloseAll,
disabledCloseCurrent,
disabledCloseLeft,
disabledCloseOther,
disabledCloseRight,
disabledRefresh,
} = getTabDisableState(tab);
2024-05-19 21:20:42 +08:00
const affixTab = tab?.meta?.affixTab ?? false;
2024-05-19 21:20:42 +08:00
const menus: IContextMenuItem[] = [
{
disabled: disabledCloseCurrent,
handler: async () => {
await closeCurrentTab(tab);
},
icon: X,
key: 'close',
text: $t('preferences.tabbar.contextMenu.close'),
},
{
handler: async () => {
await toggleTabPin(tab);
},
icon: affixTab ? PinOff : Pin,
key: 'affix',
text: affixTab
? $t('preferences.tabbar.contextMenu.unpin')
: $t('preferences.tabbar.contextMenu.pin'),
},
{
handler: async () => {
if (!contentIsMaximize.value) {
await router.push(tab.fullPath);
}
toggleMaximize();
},
icon: contentIsMaximize.value ? Minimize2 : Fullscreen,
key: contentIsMaximize.value ? 'restore-maximize' : 'maximize',
text: contentIsMaximize.value
? $t('preferences.tabbar.contextMenu.restoreMaximize')
: $t('preferences.tabbar.contextMenu.maximize'),
},
2024-05-19 21:20:42 +08:00
{
disabled: disabledRefresh,
handler: refreshTab,
icon: RotateCw,
2024-05-19 21:20:42 +08:00
key: 'reload',
text: $t('preferences.tabbar.contextMenu.reload'),
2024-05-19 21:20:42 +08:00
},
{
handler: async () => {
await openTabInNewWindow(tab);
},
icon: ExternalLink,
key: 'open-in-new-window',
separator: true,
text: $t('preferences.tabbar.contextMenu.openInNewWindow'),
},
2024-05-19 21:20:42 +08:00
{
disabled: disabledCloseLeft,
2024-05-19 21:20:42 +08:00
handler: async () => {
await closeLeftTabs(tab);
2024-05-19 21:20:42 +08:00
},
icon: ArrowLeftToLine,
2024-05-19 21:20:42 +08:00
key: 'close-left',
text: $t('preferences.tabbar.contextMenu.closeLeft'),
2024-05-19 21:20:42 +08:00
},
{
disabled: disabledCloseRight,
2024-05-19 21:20:42 +08:00
handler: async () => {
await closeRightTabs(tab);
2024-05-19 21:20:42 +08:00
},
icon: ArrowRightToLine,
2024-05-19 21:20:42 +08:00
key: 'close-right',
separator: true,
text: $t('preferences.tabbar.contextMenu.closeRight'),
2024-05-19 21:20:42 +08:00
},
{
disabled: disabledCloseOther,
2024-05-19 21:20:42 +08:00
handler: async () => {
await closeOtherTabs(tab);
2024-05-19 21:20:42 +08:00
},
icon: FoldHorizontal,
2024-05-19 21:20:42 +08:00
key: 'close-other',
text: $t('preferences.tabbar.contextMenu.closeOther'),
2024-05-19 21:20:42 +08:00
},
{
disabled: disabledCloseAll,
handler: closeAllTabs,
icon: ArrowRightLeft,
2024-05-19 21:20:42 +08:00
key: 'close-all',
text: $t('preferences.tabbar.contextMenu.closeAll'),
2024-05-19 21:20:42 +08:00
},
];
return menus;
};
return {
createContextMenus,
currentActive,
currentTabs,
handleClick,
handleClose,
};
}