效果展示

代码片段
<template>
<div v-if="props.isTitle && props.title" class="wrapper-header">
<div class="line"></div>
<div>{{ props.title }}</div>
</div>
<div class="tab-wrapper" :style="{...topWrapperStyle}">
<div
:class="['tab-item', currentActive == item.value ? 'active' : '']"
v-for="item in props.tabList"
:key="item.id"
@click="hanldeClick(item)"
:style="{...topItemStyle}"
>
{{ item.label }}
</div>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
interface tabListInt {
id: number;
label: string;
value: string | number;
}
interface Props {
tabList: Array<tabListInt>;
isTitle?: boolean;
title?: string;
isActive?: boolean;
modelValue: string | number;
topWrapperStyle?: {};
topItemStyle?: {};
}
const props = withDefaults(defineProps<Props>(), { isTitle: true, isActive: true });
const emit = defineEmits(["update:modelValue"]);
const currentActive = ref<string | number>();
const hanldeClick = (item: tabListInt) => {
if (props.isActive) {
currentActive.value = item.value;
}
emit("update:modelValue", item.value);
};
onMounted(() => {
if (props.isActive) {
currentActive.value = props.modelValue
}
})
</script>
<style lang="scss" scoped>
.wrapper-header {
display: flex;
align-items: center;
font-size: 14px;
font-weight: bold;
margin: 10px 0;
color: #888;
.line {
width: 3px;
height: 15px;
margin-right: 5px;
background-color: #1e90ff;
}
}
.tab-wrapper {
display: flex;
flex-wrap: wrap;
.tab-item {
margin-right: 10px;
border: 1px solid rgba(0, 0, 0, 0.3);
padding: 8px 13px;
margin-bottom: 10px;
border-radius: 8px;
color: #888;
&.active {
color: #fff;
background-color: #1e90ff;
border-color: #1e90ff;
}
}
}
</style>