137 lines
3.9 KiB
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>
|