feat: multiple tabs support action (#297)

* feat: multiple tabs support action

* refactor: tap change to tab

* feat(tab-router): handle operation effect

Co-authored-by: Uyarn <uyarnchen@gmail.com>
This commit is contained in:
paopao 2022-09-14 12:27:02 +08:00 committed by GitHub
parent fc69c8f9eb
commit 12e869ddeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -19,19 +19,23 @@
<t-dropdown <t-dropdown
trigger="context-menu" trigger="context-menu"
:min-column-width="128" :min-column-width="128"
:popup-props="{ overlayClassName: 'route-tabs-dropdown' }" :popup-props="{
overlayClassName: 'route-tabs-dropdown',
onVisibleChange: (visible: boolean, ctx) => handleTabMenuClick(visible, ctx, routeItem.path),
visible: activeTabPath === routeItem.path,
}"
> >
<template v-if="!routeItem.isHome"> <template v-if="!routeItem.isHome">
{{ routeItem.title }} {{ routeItem.title }}
</template> </template>
<t-icon v-else name="home" /> <t-icon v-else name="home" />
<template #dropdown> <template #dropdown>
<t-dropdown-menu v-if="$route.path === routeItem.path"> <t-dropdown-menu>
<t-dropdown-item @click="() => handleRefresh(routeItem, index)"> <t-dropdown-item @click="() => handleRefresh(routeItem, index)">
<t-icon name="refresh" /> <t-icon name="refresh" />
刷新 刷新
</t-dropdown-item> </t-dropdown-item>
<t-dropdown-item v-if="index > 0" @click="() => handleCloseAhead(routeItem.path, index)"> <t-dropdown-item v-if="index > 1" @click="() => handleCloseAhead(routeItem.path, index)">
<t-icon name="arrow-left" /> <t-icon name="arrow-left" />
关闭左侧 关闭左侧
</t-dropdown-item> </t-dropdown-item>
@ -42,7 +46,7 @@
<t-icon name="arrow-right" /> <t-icon name="arrow-right" />
关闭右侧 关闭右侧
</t-dropdown-item> </t-dropdown-item>
<t-dropdown-item @click="() => handleCloseOther(routeItem.path, index)"> <t-dropdown-item v-if="tabRouters.length > 2" @click="() => handleCloseOther(routeItem.path, index)">
<t-icon name="close-circle" /> <t-icon name="close-circle" />
关闭其它 关闭其它
</t-dropdown-item> </t-dropdown-item>
@ -63,7 +67,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { nextTick, computed } from 'vue'; import { nextTick, ref, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { useSettingStore, useTabsRouterStore } from '@/store'; import { useSettingStore, useTabsRouterStore } from '@/store';
import { prefix } from '@/config/global'; import { prefix } from '@/config/global';
@ -79,6 +83,7 @@ const router = useRouter();
const settingStore = useSettingStore(); const settingStore = useSettingStore();
const tabsRouterStore = useTabsRouterStore(); const tabsRouterStore = useTabsRouterStore();
const tabRouters = computed(() => tabsRouterStore.tabRouters.filter((route) => route.isAlive || route.isHome)); const tabRouters = computed(() => tabsRouterStore.tabRouters.filter((route) => route.isAlive || route.isHome));
const activeTabPath = ref('');
const handleChangeCurrentTab = (path: string) => { const handleChangeCurrentTab = (path: string) => {
const { tabRouters } = tabsRouterStore; const { tabRouters } = tabsRouterStore;
@ -100,14 +105,46 @@ const handleRefresh = (route: TRouterInfo, routeIdx: number) => {
tabsRouterStore.toggleTabRouterAlive(routeIdx); tabsRouterStore.toggleTabRouterAlive(routeIdx);
router.replace({ path: route.path, query: route.query }); router.replace({ path: route.path, query: route.query });
}); });
activeTabPath.value = null;
}; };
const handleCloseAhead = (path: string, routeIdx: number) => { const handleCloseAhead = (path: string, routeIdx: number) => {
tabsRouterStore.subtractTabRouterAhead({ path, routeIdx }); tabsRouterStore.subtractTabRouterAhead({ path, routeIdx });
handleOperationEffect('ahead', routeIdx);
}; };
const handleCloseBehind = (path: string, routeIdx: number) => { const handleCloseBehind = (path: string, routeIdx: number) => {
tabsRouterStore.subtractTabRouterBehind({ path, routeIdx }); tabsRouterStore.subtractTabRouterBehind({ path, routeIdx });
handleOperationEffect('behind', routeIdx);
}; };
const handleCloseOther = (path: string, routeIdx: number) => { const handleCloseOther = (path: string, routeIdx: number) => {
tabsRouterStore.subtractTabRouterOther({ path, routeIdx }); tabsRouterStore.subtractTabRouterOther({ path, routeIdx });
handleOperationEffect('other', routeIdx);
};
//
const handleOperationEffect = (type: 'other' | 'ahead' | 'behind', routeIndex: number) => {
const currentPath = router.currentRoute.value.path;
const { tabRouters } = tabsRouterStore;
const currentIdx = tabRouters.findIndex((i) => i.path === currentPath);
//
//
const needRefreshRouter =
(type === 'other' && currentIdx !== routeIndex) ||
(type === 'ahead' && currentIdx < routeIndex) ||
(type === 'behind' && currentIdx === -1);
if (needRefreshRouter) {
const nextRouteIdx = type === 'behind' ? tabRouters.length - 1 : 1;
const nextRouter = tabRouters[nextRouteIdx];
router.push({ path: nextRouter.path, query: nextRouter.query });
}
activeTabPath.value = null;
};
const handleTabMenuClick = (visible: boolean, ctx, path: string) => {
if (ctx.trigger === 'document') activeTabPath.value = null;
if (visible) activeTabPath.value = path;
}; };
</script> </script>