Files
front-pc/components/kl-tab-bar/index.vue
2025-09-04 22:17:09 +08:00

151 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-tabs
v-model="tabActive"
:class="['demo-tabs', { 'no-border': !border, 'page-header': pageHeader }]"
:before-leave="() => !loading"
@tab-change="handleChange"
>
<el-tab-pane v-for="(item, index) in data" :key="index" :label="item.label" :name="item.value">
<template v-if="showNum" #label>
<img v-if="item.value === tabActive && showIcon" src="~/assets/images/2.png" alt="" srcset="" class="mr-[7px]" />
<span>{{ item.label }}</span>
<el-badge :value="item.num" class="item" :max="9999999999999" :hidden="!item.num" />
</template>
</el-tab-pane>
</el-tabs>
</template>
<script lang="ts" setup>
import type { TabPaneName } from 'element-plus'
import type { PropType } from 'vue'
import { computed } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const props = defineProps({
data: {
type: Array as PropType<{ num?: number; label: string; value: string | number; [key: string]: any }[]>,
default: () => [],
},
loading: {
type: Boolean,
default: false,
},
border: {
//是否显示底边框
type: Boolean,
default: false,
},
showNum: {
//显示数量
type: Boolean,
default: true,
},
pageHeader: {
//是否是页面头部
type: Boolean,
default: false,
},
modelValue: {
type: [Number, String],
default: 0,
},
/**切换是否是路由模式true则会跳转到对应value值中的路由页面*/
route: {
type: Boolean,
default: false,
},
showIcon: {
type: Boolean,
default: false,
},
})
const emits = defineEmits<{
(e: 'update:modelValue', value: number | string): void
(e: 'change', value: TabPaneName): void
}>()
const tabActive = computed({
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
},
})
const handleChange = (name: TabPaneName) => {
if (props.route && name) {
router.push(name as string)
return
}
emits('change', name)
}
</script>
<style lang="scss" scoped>
:deep(.el-tabs__nav-wrap::after) {
height: 1px;
}
.no-border :deep(.el-tabs__nav-wrap::after) {
display: none;
}
:deep(.el-tabs__header) {
margin-bottom: 10px;
}
:deep(.el-tabs__item) {
height: auto;
padding-bottom: 8px;
color: #333333;
font-size: 20px;
margin-right: 40px;
}
:deep(.el-tabs__item > span) {
margin-right: 2px;
}
.page-header {
padding: 6px 10px 8px;
:deep(.el-tabs__header) {
margin-bottom: 0;
}
}
.page-header :deep(.el-tabs__item) {
font-size: 15px;
}
:deep(.el-tabs__item.is-active),
:deep(.el-tabs__item:hover) {
color: #1a65ff !important;
}
.page-table-wrap > .el-tabs.el-tabs--top :deep(.el-tabs__active-bar.is-top) {
height: 2px;
background-color: transparent;
padding: 0;
box-sizing: border-box !important;
}
.page-table-wrap > .el-tabs.el-tabs--top :deep(.el-tabs__active-bar.is-top::before) {
content: '';
height: 2px;
display: block;
background: $color-primary;
width: var(--actbar-w);
}
.page-header :deep(.el-tabs__item.is-active) {
font-weight: 600;
}
.page-header :deep(.el-tabs__active-bar.is-top) {
height: 4px;
background-color: transparent;
padding: 0;
box-sizing: border-box !important;
}
.page-header :deep(.el-tabs__active-bar.is-top::before) {
content: '';
border-radius: 2px;
height: 4px;
width: 20px;
display: block;
background: $color-primary;
margin: auto;
}
:deep(.el-badge) {
display: flex;
}
</style>