njzscloud-dispose-web/src/pages/a-frame/ATabbar.vue

192 lines
4.8 KiB
Vue

<template>
<div class="a-tabs">
<ElScrollbar
ref="tabsScrollbar"
class="a-tabs-scrollbar"
>
<div class="a-tabs-wrapper">
<div v-for="(item,i) in appPageStore.pages"
:id="item.insId"
:key="'a-frame-header-tab'+i"
:class="{'a-tab-item-active': item.insId === appPageStore.currentPage.insId}"
class="a-tab-item"
@click="Nav.open(item.routeName)">
<div>
<AIcon :name="item.icon as IconName"/>
<div class="title">{{ item.title }}</div>
</div>
<div v-if="item.routeName === SpecialPage.Home"></div>
<ElButton v-else :icon="elIcons.Close" text @click.stop="Nav.close(item.insId)"/>
</div>
</div>
</ElScrollbar>
<ElDropdown placement="bottom" @command="handleCommand">
<ElButton :icon="elIcons.More" text/>
<template #dropdown>
<ElDropdownMenu>
<ElDropdownItem :icon="elIcons.ArrowLeft" command="closeLeft">关闭左侧</ElDropdownItem>
<ElDropdownItem :icon="elIcons.ArrowRight" command="closeRight">关闭右侧</ElDropdownItem>
<ElDropdownItem :icon="elIcons.Close" command="closeOther">关闭其他</ElDropdownItem>
<ElDropdownItem :icon="elIcons.CircleClose" command="closeAll"></ElDropdownItem>
</ElDropdownMenu>
</template>
</ElDropdown>
</div>
</template>
<script lang="ts" setup>
import { useAppPageStore } from '@/common/app/app-page-store.ts'
import { elIcons } from '@/common/element/element.ts'
import type { IconName } from '@/components/a-icon/iconfont.ts'
import AIcon from '@/components/a-icon/AIcon.vue'
import type { ScrollbarInstance } from 'element-plus'
import Nav from '@/common/router/nav.ts'
import { SpecialPage } from '@/common/router/constants.ts'
const appPageStore = useAppPageStore()
const tabsScrollbarIns = useTemplateRef<ScrollbarInstance>('tabsScrollbar')
watch(
() => appPageStore.currentPage.insId,
() => {
nextTick(() => {
const tabItem = document.getElementById(appPageStore.currentPage.insId)
if (tabItem != null) tabsScrollbarIns.value?.setScrollLeft(tabItem.offsetLeft)
})
})
function reopen(insId: string) {
appPageStore.reopen(insId)
}
function handleCommand(command: 'closeCurrent' | 'closeOther' | 'closeAll') {
Nav[command]()
}
</script>
<style lang="stylus" scoped>
.a-tabs {
height 42px
width 100%;
box-sizing border-box
//border-top 1px solid #EAEBF1;
//border-bottom 1px solid #EAEBF1;
display flex
justify-content space-between
align-items center
color #303133
padding: 0 5px;
gap 10px
.a-tabs-scrollbar {
height 100%
//width calc(100% - 52px);
flex 1
box-sizing border-box
:deep(.el-scrollbar__wrap) {
height 100%
box-sizing border-box
scroll-behavior: smooth;
}
:deep(.el-scrollbar__view) {
height 100%
box-sizing border-box
}
}
.a-tabs-wrapper {
height 100%
width: fit-content;
display flex
box-sizing border-box
align-items center
padding 5px 5px 0 0
gap 12px
.a-tab-item {
height 100%
padding 5px 10px
cursor pointer
display flex
justify-content space-between
gap 20px
align-items center
box-sizing border-box
position relative
border 1px solid #EAEBF1
box-shadow: 0 0 0 rgba(0, 0, 0, 0.2);
transition color, box-shadow, border 0.2s ease-in-out
font-size 14px
background-color white
border-radius 5px
text-wrap: nowrap;
color #7987A1
&::after {
content ''
height 1px
width 0
background-color var(--main-color)
margin auto
box-sizing border-box
position absolute
bottom 0
left: 50%;
transform: translateX(-50%);
transition width 0.2s ease-in-out
}
&.a-tab-item-active {
color var(--main-color)
//border 1px solid var(--main-color)
}
&:not(.a-tab-item-active):hover {
color var(--main-color)
box-shadow: 0 0 3px rgba(0, 0, 0, 0.12);
&::after {
width 95%
}
}
& > div:first-child {
display flex
gap 10px
align-items center
}
& > button {
padding 0
width 14px
height 14px !important
line-height 14px
border-radius 50%
color #7987A1
&:hover {
color var(--el-color-danger)
}
}
}
}
:deep(.el-dropdown) {
width: 32px;
padding: 0;
background-color white
& > button {
background-color white
border: 1px solid var(--el-button-border-color);
padding: 0;
width: 32px;
outline: none !important;
outline-offset unset !important
}
}
}
</style>