element-plus/packages/tabs/src/tab-bar.vue

80 lines
2.1 KiB
Vue
Raw Normal View History

2020-08-14 09:49:31 +08:00
<template>
<div
:class="['el-tabs__active-bar', `is-${ rootTabs.props.tabPosition }`]"
:style="barStyle"
></div>
</template>
<script lang='ts'>
2020-08-23 10:35:36 +08:00
import { defineComponent, inject, getCurrentInstance, watch, nextTick, ref, PropType } from 'vue'
2020-08-14 09:49:31 +08:00
import { capitalize } from '@vue/shared'
2020-08-23 10:35:36 +08:00
import { Pane, RootTabs } from './tabs.vue'
2020-08-14 09:49:31 +08:00
export default defineComponent({
name: 'ElTabBar',
props: {
tabs: {
2020-08-23 10:35:36 +08:00
type: Array as PropType<Pane[]>,
default: () => ([] as Pane[]),
2020-08-14 09:49:31 +08:00
},
},
setup(props) {
2020-08-23 10:35:36 +08:00
const rootTabs = inject<RootTabs>('rootTabs')
2020-08-14 09:49:31 +08:00
if (!rootTabs) {
throw new Error(`ElTabBar must use with ElTabs`)
}
const instance = getCurrentInstance()
const getBarStyle = () => {
2020-08-21 21:10:19 +08:00
let style = {} as CSSStyleDeclaration
2020-08-14 09:49:31 +08:00
let offset = 0
let tabSize = 0
const sizeName = ['top', 'bottom'].includes(rootTabs.props.tabPosition) ? 'width' : 'height'
const sizeDir = sizeName === 'width' ? 'x' : 'y'
2020-08-20 16:28:07 +08:00
props.tabs.every(tab => {
2020-08-23 10:35:36 +08:00
let $el = instance.parent.refs?.[`tab-${tab.paneName}`] as Element
2020-08-14 09:49:31 +08:00
if (!$el) { return false }
2020-08-23 10:35:36 +08:00
if (!tab.active) {
2020-08-14 09:49:31 +08:00
offset += $el[`client${capitalize(sizeName)}`]
return true
} else {
tabSize = $el[`client${capitalize(sizeName)}`]
const tabStyles = window.getComputedStyle($el)
if (sizeName === 'width') {
if (props.tabs.length > 1) {
tabSize -= parseFloat(tabStyles.paddingLeft) + parseFloat(tabStyles.paddingRight)
}
offset += parseFloat(tabStyles.paddingLeft)
}
return false
}
})
const transform = `translate${capitalize(sizeDir)}(${offset}px)`
style[sizeName] = `${tabSize}px`
style.transform = transform
style.msTransform = transform
style.webkitTransform = transform
return style
}
const barStyle = ref(getBarStyle())
watch(() => props.tabs, () => {
nextTick(() => {
barStyle.value = getBarStyle()
})
})
return {
rootTabs,
barStyle,
}
},
})
</script>