You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.4 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup lang="ts">
import { storeToRefs } from 'pinia'
import type { RouteLocationNormalized } from 'vue-router'
import TabRedo from './components/tab-redo.vue'
import TabQuick from './components/tab-quick.vue'
import TabFoldButton from './components/tab-foldbutton.vue'
import TabDropDown from './components/tab-dropdown.vue'
import type { TabDropDownInst } from './components/types'
import { REDIRECT_NAME } from '~/constants'
import { Sortable, listenerRouteChange } from '~/utils'
const router = useRouter()
const go = useGo()
const { close } = useTabs()
const multipleTabStore = useMultipleTabStore()
const { tabList } = storeToRefs(multipleTabStore)
const { getShowFold, getShowQuick, getShowRedo } = useMultipleTabSetting()
let activeTabName = $ref<string>('')
const tabDropdownRef = $ref<TabDropDownInst | null>(null)
const tabListRef = computed(() => {
return unref(tabList).filter(item => !item.meta?.hideInTab && router.hasRoute(item.name!))
})
listenerRouteChange((route) => {
const { name } = route
// TODO accessToken
if (name === REDIRECT_NAME || !route) {
return
}
const { path, fullPath, meta = {} } = route
const { currentActiveMenu, hideInTab } = meta
const isHide = !hideInTab ? null : currentActiveMenu
const p = isHide || fullPath || path
if (activeTabName !== p) {
activeTabName = p as string
}
if (isHide) {
const findParentRoute = router.getRoutes().find(item => item.path === currentActiveMenu)
findParentRoute && multipleTabStore.checkTab(findParentRoute as unknown as RouteLocationNormalized)
}
else {
multipleTabStore.checkTab(unref(route))
}
})
function handleChange(value: string) {
go(value, false)
}
// 获取tabs内dom拖拽
nextTick(() => {
const selection = document.querySelector(
'#drag > div > div > div > div > div.n-tabs-wrapper',
)
Sortable.create(selection as HTMLElement, {
animation: 150,
})
})
function handleContextMenu(e: MouseEvent, tabItem: RouteLocationNormalized) {
e.preventDefault()
if (!tabItem) {
return
}
unref(tabDropdownRef)?.openDropdown(e, tabItem)
}
function handleClose(e: MouseEvent, route: RouteLocationNormalized) {
e.stopPropagation()
close(route)
}
</script>
<template>
<NEl class="mt-2">
<NTabs
id="drag"
v-model:value="activeTabName"
type="card"
:tabs-padding="8"
animated
@update:value="handleChange"
>
<NTab
v-for="(item, index) in tabListRef"
:key="item.query ? item.fullPath : item.path"
:name="item.fullPath"
style="--n-tab-padding: 0"
>
<div
class="group py-4px pl-12px hover:text-[var(--n-tab-text-color-active)]"
:class="[index === 0 ? 'pr-12px' : 'pr-18px']"
@contextmenu="handleContextMenu($event, item)"
>
<span>{{ $t(item.meta.title || '') }}</span>
<LIcon
v-if="index !== 0"
icon="ant-design:close-outlined"
class="hover:nt--7px absolute top-1/2 ml-2px mt--6px inline-flex !transition-all hover:!text-14px"
:class="{ ['!hidden']: activeTabName !== item.fullPath }"
size="14"
@click="handleClose($event, item)"
/>
</div>
</NTab>
<template #suffix>
<TabRedo v-if="getShowRedo" />
<TabQuick v-if="getShowQuick" :tab-item="$route" />
<TabFoldButton v-if="getShowFold" />
</template>
</NTabs>
<TabDropDown ref="tabDropdownRef" />
</NEl>
</template>