123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- import type { IContextMenuItem } from '@vben-core/tabs-ui';
- import type { TabItem } from '@vben-core/typings';
- import type {
- RouteLocationNormalized,
- RouteLocationNormalizedGeneric,
- } from 'vue-router';
- import { computed, ref, watch } from 'vue';
- import { useRoute, useRouter } from 'vue-router';
- import {
- IcRoundClose,
- IcRoundMultipleStop,
- IcRoundRefresh,
- MdiArrowExpandHorizontal,
- MdiFormatHorizontalAlignLeft,
- MdiFormatHorizontalAlignRight,
- MdiPin,
- MdiPinOff,
- } from '@vben-core/iconify';
- import { $t, useI18n } from '@vben-core/locales';
- import {
- storeToRefs,
- useCoreAccessStore,
- useCoreTabbarStore,
- } from '@vben-core/stores';
- import { filterTree } from '@vben-core/toolkit';
- function useTabs() {
- const router = useRouter();
- const route = useRoute();
- const accessStore = useCoreAccessStore();
- const coreTabbarStore = useCoreTabbarStore();
- const { accessMenus } = storeToRefs(accessStore);
- const currentActive = computed(() => {
- return route.path;
- });
- const { locale } = useI18n();
- const currentTabs = ref<RouteLocationNormalizedGeneric[]>();
- watch([() => coreTabbarStore.getTabs, () => locale.value], ([tabs, _]) => {
- currentTabs.value = tabs.map((item) => wrapperTabLocale(item));
- });
- /**
- * 初始化固定标签页
- */
- const initAffixTabs = () => {
- const affixTabs = filterTree(router.getRoutes(), (route) => {
- return !!route.meta?.affixTab;
- });
- coreTabbarStore.setAffixTabs(affixTabs);
- };
- // 点击tab,跳转路由
- const handleClick = (key: string) => {
- router.push(key);
- };
- // 关闭tab
- const handleClose = async (key: string) => {
- await coreTabbarStore.closeTabByKey(key, router);
- };
- function wrapperTabLocale(tab: RouteLocationNormalizedGeneric) {
- return {
- ...tab,
- meta: {
- ...tab.meta,
- title: $t(tab.meta.title as string),
- },
- };
- }
- watch(
- () => accessMenus.value,
- () => {
- initAffixTabs();
- },
- { immediate: true },
- );
- watch(
- () => route.path,
- () => {
- coreTabbarStore.addTab(route as RouteLocationNormalized);
- },
- { immediate: true },
- );
- const createContextMenus = (tab: TabItem) => {
- const tabs = coreTabbarStore.getTabs;
- const affixTabs = coreTabbarStore.affixTabs;
- const index = tabs.findIndex((item) => item.path === tab.path);
- const disabled = tabs.length <= 1;
- const { meta } = tab;
- const affixTab = meta?.affixTab ?? false;
- const isCurrentTab = route.path === tab.path;
- // 当前处于最左侧或者减去固定标签页的数量等于0
- const closeLeftDisabled =
- index === 0 || index - affixTabs.length <= 0 || !isCurrentTab;
- const closeRightDisabled = !isCurrentTab || index === tabs.length - 1;
- const closeOtherDisabled =
- disabled || !isCurrentTab || tabs.length - affixTabs.length <= 1;
- const menus: IContextMenuItem[] = [
- {
- disabled: !isCurrentTab,
- handler: async () => {
- await coreTabbarStore.refresh(router);
- },
- icon: IcRoundRefresh,
- key: 'reload',
- text: $t('preferences.tabbar.context-menu.reload'),
- },
- {
- disabled: !!affixTab || disabled,
- handler: async () => {
- await coreTabbarStore.closeTab(tab, router);
- },
- icon: IcRoundClose,
- key: 'close',
- text: $t('preferences.tabbar.context-menu.close'),
- },
- {
- handler: async () => {
- await (affixTab
- ? coreTabbarStore.unpinTab(tab)
- : coreTabbarStore.pinTab(tab));
- },
- icon: affixTab ? MdiPinOff : MdiPin,
- key: 'affix',
- separator: true,
- text: affixTab
- ? $t('preferences.tabbar.context-menu.unpin')
- : $t('preferences.tabbar.context-menu.pin'),
- },
- {
- disabled: closeLeftDisabled,
- handler: async () => {
- await coreTabbarStore.closeLeftTabs(tab);
- },
- icon: MdiFormatHorizontalAlignLeft,
- key: 'close-left',
- text: $t('preferences.tabbar.context-menu.close-left'),
- },
- {
- disabled: closeRightDisabled,
- handler: async () => {
- await coreTabbarStore.closeRightTabs(tab);
- },
- icon: MdiFormatHorizontalAlignRight,
- key: 'close-right',
- separator: true,
- text: $t('preferences.tabbar.context-menu.close-right'),
- },
- {
- disabled: closeOtherDisabled,
- handler: async () => {
- await coreTabbarStore.closeOtherTabs(tab);
- },
- icon: MdiArrowExpandHorizontal,
- key: 'close-other',
- text: $t('preferences.tabbar.context-menu.close-other'),
- },
- {
- disabled,
- handler: async () => {
- await coreTabbarStore.closeAllTabs(router);
- },
- icon: IcRoundMultipleStop,
- key: 'close-all',
- text: $t('preferences.tabbar.context-menu.close-all'),
- },
- // {
- // icon: 'icon-[material-symbols--back-to-tab-sharp]',
- // key: 'close-all',
- // text: '新窗口打开',
- // },
- ];
- return menus;
- };
- /**
- * 取消固定标签页
- */
- const handleUnpinTab = async (tab: TabItem) => {
- await coreTabbarStore.unpinTab(tab);
- };
- return {
- createContextMenus,
- currentActive,
- currentTabs,
- handleClick,
- handleClose,
- handleUnpinTab,
- };
- }
- export { useTabs };
|