mirror of
https://github.com/certd/certd.git
synced 2026-05-15 04:27:31 +08:00
🔱: [client] sync upgrade with 7 commits [trident-sync]
chore: Merge branch 'vben' # Conflicts: # package.json perf: antdv示例改成使用vben框架 chore: vben chore: vben chore: vben
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export { default as LayoutTabbar } from "./tabbar.vue";
|
||||
export * from "./use-tabbar";
|
||||
@@ -0,0 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import { useContentMaximize, useTabs } from "../../../hooks";
|
||||
import { preferences } from "../../../preferences";
|
||||
import { useTabbarStore } from "../../../stores";
|
||||
|
||||
import { TabsToolMore, TabsToolScreen, TabsView } from "../../../tabs-ui";
|
||||
|
||||
import { useTabbar } from "./use-tabbar";
|
||||
|
||||
defineOptions({
|
||||
name: "LayoutTabbar"
|
||||
});
|
||||
|
||||
defineProps<{ showIcon?: boolean; theme?: string }>();
|
||||
|
||||
const route = useRoute();
|
||||
const tabbarStore = useTabbarStore();
|
||||
const { contentIsMaximize, toggleMaximize } = useContentMaximize();
|
||||
const { unpinTab } = useTabs();
|
||||
|
||||
const { createContextMenus, currentActive, currentTabs, handleClick, handleClose } = useTabbar();
|
||||
|
||||
const menus = computed(() => {
|
||||
const tab = tabbarStore.getTabByPath(currentActive.value);
|
||||
const menus = createContextMenus(tab);
|
||||
return menus.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
label: item.text,
|
||||
value: item.key
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// 刷新后如果不保持tab状态,关闭其他tab
|
||||
if (!preferences.tabbar.persist) {
|
||||
tabbarStore.closeOtherTabs(route);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TabsView
|
||||
:active="currentActive"
|
||||
:class="theme"
|
||||
:context-menus="createContextMenus"
|
||||
:draggable="preferences.tabbar.draggable"
|
||||
:show-icon="showIcon"
|
||||
:style-type="preferences.tabbar.styleType"
|
||||
:tabs="currentTabs"
|
||||
:wheelable="preferences.tabbar.wheelable"
|
||||
:middle-click-to-close="preferences.tabbar.middleClickToClose"
|
||||
@close="handleClose"
|
||||
@sort-tabs="tabbarStore.sortTabs"
|
||||
@unpin="unpinTab"
|
||||
@update:active="handleClick"
|
||||
/>
|
||||
<div class="flex-center h-full">
|
||||
<TabsToolMore v-if="preferences.tabbar.showMore" :menus="menus" />
|
||||
<TabsToolScreen v-if="preferences.tabbar.showMaximize" :screen="contentIsMaximize" @change="toggleMaximize" @update:screen="toggleMaximize" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,181 @@
|
||||
import type { RouteLocationNormalizedGeneric } from "vue-router";
|
||||
|
||||
import type { TabDefinition } from "../../../types";
|
||||
|
||||
import type { IContextMenuItem } from "../../../tabs-ui";
|
||||
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
import { useContentMaximize, useTabs } from "../../../hooks";
|
||||
import { ArrowLeftToLine, ArrowRightLeft, ArrowRightToLine, ExternalLink, FoldHorizontal, Fullscreen, Minimize2, Pin, PinOff, RotateCw, X } from "../../../icons";
|
||||
import { $t, useI18n } from "../../../locales";
|
||||
import { useAccessStore, useTabbarStore } from "../../../stores";
|
||||
import { filterTree } from "../../../utils";
|
||||
|
||||
export function useTabbar() {
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const accessStore = useAccessStore();
|
||||
const tabbarStore = useTabbarStore();
|
||||
const { contentIsMaximize, toggleMaximize } = useContentMaximize();
|
||||
const { closeAllTabs, closeCurrentTab, closeLeftTabs, closeOtherTabs, closeRightTabs, closeTabByKey, getTabDisableState, openTabInNewWindow, refreshTab, toggleTabPin } = useTabs();
|
||||
|
||||
const currentActive = computed(() => {
|
||||
return route.fullPath;
|
||||
});
|
||||
|
||||
const { locale } = useI18n();
|
||||
const currentTabs = ref<RouteLocationNormalizedGeneric[]>();
|
||||
watch([() => tabbarStore.getTabs, () => tabbarStore.updateTime, () => locale.value], ([tabs]) => {
|
||||
currentTabs.value = tabs.map((item: any) => wrapperTabLocale(item));
|
||||
});
|
||||
|
||||
/**
|
||||
* 初始化固定标签页
|
||||
*/
|
||||
const initAffixTabs = () => {
|
||||
const affixTabs = filterTree(router.getRoutes(), (route: any) => {
|
||||
return !!route.meta?.affixTab;
|
||||
});
|
||||
tabbarStore.setAffixTabs(affixTabs);
|
||||
};
|
||||
|
||||
// 点击tab,跳转路由
|
||||
const handleClick = (key: string) => {
|
||||
router.push(key);
|
||||
};
|
||||
|
||||
// 关闭tab
|
||||
const handleClose = async (key: string) => {
|
||||
await closeTabByKey(key);
|
||||
};
|
||||
|
||||
function wrapperTabLocale(tab: RouteLocationNormalizedGeneric) {
|
||||
return {
|
||||
...tab,
|
||||
meta: {
|
||||
...tab?.meta,
|
||||
title: $t(tab?.meta?.title as string)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
watch(
|
||||
() => accessStore.accessMenus,
|
||||
() => {
|
||||
initAffixTabs();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
const meta = route.matched?.[route.matched.length - 1]?.meta;
|
||||
tabbarStore.addTab({
|
||||
...route,
|
||||
meta: meta || route.meta
|
||||
});
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const createContextMenus = (tab: TabDefinition) => {
|
||||
const { disabledCloseAll, disabledCloseCurrent, disabledCloseLeft, disabledCloseOther, disabledCloseRight, disabledRefresh } = getTabDisableState(tab);
|
||||
|
||||
const affixTab = tab?.meta?.affixTab ?? false;
|
||||
|
||||
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")
|
||||
},
|
||||
{
|
||||
disabled: disabledRefresh,
|
||||
handler: refreshTab,
|
||||
icon: RotateCw,
|
||||
key: "reload",
|
||||
text: $t("preferences.tabbar.contextMenu.reload")
|
||||
},
|
||||
{
|
||||
handler: async () => {
|
||||
await openTabInNewWindow(tab);
|
||||
},
|
||||
icon: ExternalLink,
|
||||
key: "open-in-new-window",
|
||||
separator: true,
|
||||
text: $t("preferences.tabbar.contextMenu.openInNewWindow")
|
||||
},
|
||||
|
||||
{
|
||||
disabled: disabledCloseLeft,
|
||||
handler: async () => {
|
||||
await closeLeftTabs(tab);
|
||||
},
|
||||
icon: ArrowLeftToLine,
|
||||
key: "close-left",
|
||||
text: $t("preferences.tabbar.contextMenu.closeLeft")
|
||||
},
|
||||
{
|
||||
disabled: disabledCloseRight,
|
||||
handler: async () => {
|
||||
await closeRightTabs(tab);
|
||||
},
|
||||
icon: ArrowRightToLine,
|
||||
key: "close-right",
|
||||
separator: true,
|
||||
text: $t("preferences.tabbar.contextMenu.closeRight")
|
||||
},
|
||||
{
|
||||
disabled: disabledCloseOther,
|
||||
handler: async () => {
|
||||
await closeOtherTabs(tab);
|
||||
},
|
||||
icon: FoldHorizontal,
|
||||
key: "close-other",
|
||||
text: $t("preferences.tabbar.contextMenu.closeOther")
|
||||
},
|
||||
{
|
||||
disabled: disabledCloseAll,
|
||||
handler: closeAllTabs,
|
||||
icon: ArrowRightLeft,
|
||||
key: "close-all",
|
||||
text: $t("preferences.tabbar.contextMenu.closeAll")
|
||||
}
|
||||
];
|
||||
return menus;
|
||||
};
|
||||
|
||||
return {
|
||||
createContextMenus,
|
||||
currentActive,
|
||||
currentTabs,
|
||||
handleClick,
|
||||
handleClose
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user