You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.3 KiB
122 lines
3.3 KiB
<script lang="ts" setup> |
|
import type { RouteLocationNormalized, RouteMeta } from 'vue-router' |
|
|
|
import { useMouse } from '@vueuse/core' |
|
|
|
import { computed, ref, unref } from 'vue' |
|
|
|
import { Tabs } from 'ant-design-vue' |
|
import { useRouter } from 'vue-router' |
|
import TabContent from './components/TabContent.vue' |
|
|
|
import { initAffixTabs, useTabsDrag } from './useMultipleTabs' |
|
import { multipleTabHeight } from '@/settings/designSetting' |
|
import { useGo } from '@/hooks/web/usePage' |
|
|
|
import { useMultipleTabStore } from '@/store/modules/multipleTab' |
|
import { useUserStore } from '@/store/modules/user' |
|
|
|
import { useDesign } from '@/hooks/web/useDesign' |
|
import { useMultipleTabSetting } from '@/hooks/setting/useMultipleTabSetting' |
|
|
|
import { REDIRECT_NAME } from '@/router/constant' |
|
import { listenerRouteChange } from '@/logics/mitt/routeChange' |
|
|
|
defineOptions({ name: 'MultipleTabs' }) |
|
|
|
const affixTextList = initAffixTabs() |
|
const activeKeyRef = ref('') |
|
|
|
useTabsDrag(affixTextList) |
|
const tabStore = useMultipleTabStore() |
|
const userStore = useUserStore() |
|
const router = useRouter() |
|
|
|
const { prefixCls } = useDesign('multiple-tabs') |
|
const go = useGo() |
|
const { getShowQuick } = useMultipleTabSetting() |
|
|
|
const getTabsState = computed(() => { |
|
return tabStore.getTabList.filter(item => !item.meta?.hideTab) |
|
}) |
|
|
|
const unClose = computed(() => unref(getTabsState).length === 1) |
|
|
|
const { y: mouseY } = useMouse() |
|
|
|
const getWrapClass = computed(() => { |
|
return [ |
|
prefixCls, |
|
{ |
|
[`${prefixCls}--hide-close`]: unref(unClose), |
|
[`${prefixCls}--hover`]: unref(mouseY) < multipleTabHeight, |
|
}, |
|
] |
|
}) |
|
|
|
listenerRouteChange((route) => { |
|
const { name } = route |
|
if (name === REDIRECT_NAME || !route || !userStore.getAccessToken) |
|
return |
|
|
|
const { path, fullPath, meta = {} } = route |
|
const { currentActiveMenu, hideTab } = meta as RouteMeta |
|
const isHide = !hideTab ? null : currentActiveMenu |
|
const p = isHide || fullPath || path |
|
if (activeKeyRef.value !== p) |
|
activeKeyRef.value = p as string |
|
|
|
if (isHide) { |
|
const findParentRoute = router.getRoutes().find(item => item.path === currentActiveMenu) |
|
|
|
findParentRoute && tabStore.addTab(findParentRoute as unknown as RouteLocationNormalized) |
|
} |
|
else { |
|
tabStore.addTab(unref(route)) |
|
} |
|
}) |
|
|
|
function handleChange(activeKey: any) { |
|
activeKeyRef.value = activeKey |
|
go(activeKey, false) |
|
} |
|
|
|
// Close the current tab |
|
function handleEdit(targetKey: string) { |
|
// Added operation to hide, currently only use delete operation |
|
if (unref(unClose)) |
|
return |
|
|
|
tabStore.closeTabByKey(targetKey, router) |
|
} |
|
</script> |
|
|
|
<template> |
|
<div :class="getWrapClass"> |
|
<Tabs |
|
type="editable-card" |
|
:animated="false" |
|
:hide-add="true" |
|
:tab-bar-gutter="3" |
|
:active-key="activeKeyRef" |
|
@change="handleChange" |
|
@edit="handleEdit" |
|
> |
|
<template v-for="item in getTabsState" :key="item.query ? item.fullPath : item.path"> |
|
<Tabs.TabPane :closable="!(item && item.meta && item.meta.affix)"> |
|
<template #tab> |
|
<TabContent :tab-item="item" /> |
|
</template> |
|
</Tabs.TabPane> |
|
</template> |
|
|
|
<template v-if="getShowQuick" #rightExtra> |
|
<TabContent is-extra :tab-item="$route" /> |
|
</template> |
|
</Tabs> |
|
</div> |
|
</template> |
|
|
|
<style lang="less"> |
|
@import './index.less'; |
|
</style>
|
|
|