mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-04-06 21:10:03 +00:00
137 lines
3.6 KiB
Vue
137 lines
3.6 KiB
Vue
<template>
|
|
<div class="tab-wrap w-full px-[16px]">
|
|
<el-tabs :closable="tabbarStore.tabLength > 1" :model-value="route.path" @tab-click="tabClick" @tab-remove="removeTab">
|
|
<el-tab-pane v-for="(tab, key, index) in tabbarStore.tabs" :name="tab.path" :key="index">
|
|
<template #label>
|
|
<el-dropdown trigger="contextmenu" placement="bottom-start">
|
|
<span :class="{ 'text-primary': route.path == tab.path }" class="tab-name">{{ tab.title }}</span>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item icon="Back" :disabled="index == 0" @click="closeLeft(tab.path)">{{t('tabs.closeLeft') }}</el-dropdown-item>
|
|
<el-dropdown-item icon="Right" :disabled="index == (tabbarStore.tabLength - 1)" @click="closeRight(tab.path)">{{t('tabs.closeRight') }}</el-dropdown-item>
|
|
<el-dropdown-item icon="Close" :disabled="tabbarStore.tabLength == 1" @click="closeOther(tab.path)">{{t('tabs.closeOther') }}</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</template>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { watch, onMounted } from 'vue'
|
|
import useTabbarStore from '@/stores/modules/tabbar'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { t } from '@/lang'
|
|
|
|
const tabbarStore = useTabbarStore()
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
onMounted(() => {
|
|
tabbarStore.addTab(route)
|
|
})
|
|
|
|
watch(route, (nval: any) => {
|
|
tabbarStore.addTab(nval)
|
|
})
|
|
|
|
/**
|
|
* 添加tab
|
|
* @param content
|
|
*/
|
|
const tabClick = (content: any) => {
|
|
const tabRoute = tabbarStore.tabs[content.props.name]
|
|
router.push({ path: tabRoute.path, query: tabRoute.query })
|
|
}
|
|
|
|
/**
|
|
* 移除tab
|
|
* @param content
|
|
*/
|
|
const removeTab = (content: any) => {
|
|
if (route.path == content) {
|
|
const tabs = Object.keys(tabbarStore.tabs)
|
|
router.push({ path: tabs[tabs.indexOf(content) - 1] })
|
|
}
|
|
tabbarStore.removeTab(content)
|
|
}
|
|
|
|
/**
|
|
* 关闭左侧
|
|
* @param path
|
|
*/
|
|
const closeLeft = (path: string) => {
|
|
const tabs = Object.keys(tabbarStore.tabs)
|
|
for (let i = tabs.indexOf(path) - 1; i >= 0; i--) {
|
|
delete tabbarStore.tabs[tabs[i]]
|
|
}
|
|
router.push({ path })
|
|
}
|
|
|
|
/**
|
|
* 关闭右侧
|
|
* @param path
|
|
*/
|
|
const closeRight = (path: string) => {
|
|
const tabs = Object.keys(tabbarStore.tabs)
|
|
for (let i = tabs.indexOf(path) + 1; i < tabs.length; i++) {
|
|
delete tabbarStore.tabs[tabs[i]]
|
|
}
|
|
router.push({ path })
|
|
}
|
|
|
|
/**
|
|
* 关闭其他
|
|
* @param path
|
|
*/
|
|
const closeOther = (path: string) => {
|
|
const tabs = Object.keys(tabbarStore.tabs)
|
|
tabs.forEach((key: string) => { key != path && delete tabbarStore.tabs[key] })
|
|
router.push({ path })
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
:deep(.el-tabs) {
|
|
.el-tabs--border-card {
|
|
border: none;
|
|
}
|
|
|
|
.el-tabs__header {
|
|
margin: 0;
|
|
}
|
|
|
|
.el-tabs__nav-wrap {
|
|
margin-bottom: 0;
|
|
|
|
&::after {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.el-tabs__content {
|
|
display: none;
|
|
}
|
|
|
|
.el-tabs__item {
|
|
display: inline-flex !important;
|
|
padding: 0 20px !important;
|
|
align-items: center;
|
|
|
|
.tab-name:focus {
|
|
outline: none !important;
|
|
}
|
|
}
|
|
|
|
.el-tabs__active-bar {
|
|
display: none;
|
|
}
|
|
|
|
.el-tabs__item.is-active {
|
|
background-color: var(--el-color-primary-light-9);
|
|
}
|
|
}
|
|
</style>
|