Files
2025_Vuejs_Mpi_Panel/src/components/global/Tabs.vue

137 lines
3.9 KiB
Vue

<template>
<div class="tabs-buttons-c" :id="'tabnav' + rnd">
<template v-for="(tab, i) in tabList">
<div
:class="['tab-button', currentTab === i ? 'tab-selected' : '']"
@click="ChangeTab(i)"
:style="[i === 0 ? tabPosition : '']">
<slot :name="'tabname' + i">{{ tab.text }}</slot>
</div>
</template>
<div class="tab-nav-button tab-nav-button-prev" @click="ChangeTab('<')">
<i class="ico-c ico-tab-nav">
<svg width="8"><use href="/src/assets/images/icons.svg#arrow"></use></svg>
</i>
</div>
<div class="tab-nav-button tab-nav-button-next" @click="ChangeTab('>')">
<i class="ico-c ico-tab-nav">
<svg width="8"><use href="/src/assets/images/icons.svg#arrow"></use></svg>
</i>
</div>
</div>
<div class="tabs-contents-c" :id="'tabs' + rnd">
<template v-for="(tabc, j) in tabList">
<div
class="tab-content tab-animate"
:style="[j === 0 ? tabContentPosition : '', { width: tabWidth + 'px' }]">
<template v-if="currentTab === j">
<slot :name="tabc.id"></slot>
</template>
</div>
</template>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, onBeforeMount, watch } from 'vue'
import { useGlobalStore } from '@/stores/globalStore'
const globalStore = useGlobalStore()
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
interface TabObj {
[key: string]: any
text: string
id: string
}
export interface Props {
tabList: TabObj[]
isUseRoute?: boolean
}
const props = withDefaults(defineProps<Props>(), { isUseRoute: false })
const currentTab = ref<number>(0)
const rnd = ref<number>(Math.ceil(Number(Math.random() * 1000000000)))
const tabWidth = ref<number>(0)
const tabPosition = ref<string>('')
const tabContentPosition = computed<string>(() => {
var tabPos = ''
let pos = -(tabWidth.value * currentTab.value)
tabPos = `margin-left:${pos}px`
return tabPos
})
const CalculateNavPosition = () => {
tabPosition.value = ''
let screenWidth = document.body.offsetWidth
if (screenWidth <= 1024) {
let pos = -(tabWidth.value * currentTab.value - 50)
tabPosition.value = `margin-left:${pos}px`
}
}
const ChangeTab = (d: number | string) => {
if (d === '<') {
if (currentTab.value !== 0) {
currentTab.value--
}
} else if (d == '>') {
if (currentTab.value !== props.tabList.length - 1) {
currentTab.value++
}
} else {
currentTab.value = Number(d)
}
if (props.isUseRoute) {
router.push({
params: { ...route.params, tabid: props.tabList[currentTab.value].id }
})
}
CalculateNavPosition()
}
const TabWidth = () => {
let screenWidth = document.body.offsetWidth
let tabel = document.getElementById('tabs' + rnd.value) as HTMLElement
if (screenWidth <= globalStore.breakPoints.tablet) {
tabWidth.value = screenWidth - 48
} else {
const menuSideW = document.querySelector('.menu-side-w')
let sideW = globalStore.sideMenu ? menuSideW!.getBoundingClientRect().width : 0
tabWidth.value = screenWidth - sideW - 48
}
}
const Resize = () => {
TabWidth()
CalculateNavPosition()
}
const RouteTabControl = () => {
if (props.isUseRoute) {
if (route.params.tabid !== undefined && route.params.tabid !== '') {
currentTab.value = props.tabList.findIndex((t) => t.id === route.params.tabid)
}
}
}
onMounted(() => {
TabWidth()
window.addEventListener('resize', Resize)
})
onBeforeMount(() => {
RouteTabControl()
})
watch(
() => globalStore.sideMenu,
() => {
TabWidth()
}
)
watch(
() => route.params.tabid,
(t) => {
RouteTabControl()
},
{ immediate: true }
)
</script>