| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- <template>
- <div class="tabs-container" :class="[`tabs-type-${type}`, { 'tabs-small': tabs.length <= 2 }]">
- <div
- v-for="(tab, index) in tabs"
- :key="index"
- class="tab-item"
- :class="{ active: isActive(index, tab) }"
- @click="handleTabClick(index, tab)"
- >
- {{ getTabTitle(tab) }}
- </div>
- </div>
- </template>
- <script setup>
- const props = defineProps({
- tabs: {
- type: Array,
- required: true,
- default: () => []
- },
- modelValue: {
- type: [Number, String],
- default: 0
- },
- type: {
- type: String,
- default: 'default', // 'default' | 'light'
- validator: (value) => ['default', 'light'].includes(value)
- }
- });
- const emit = defineEmits(['update:modelValue', 'change']);
- // 判断是否为对象格式的 tab
- const isObjectTab = (tab) => {
- return typeof tab === 'object' && tab !== null && (tab.title !== undefined || tab.label !== undefined || tab.name !== undefined);
- };
- // 获取 tab 的标题
- const getTabTitle = (tab) => {
- if (isObjectTab(tab)) {
- return tab.title || tab.label || tab.name || '';
- }
- return tab;
- };
- // 判断当前 tab 是否激活
- const isActive = (index, tab) => {
- if (isObjectTab(tab)) {
- // 对象格式:比较 value
- if(tab.value){
- return props.modelValue === tab.value;
- }else{
- return props.modelValue === tab.id;
- }
- }
- // 字符串/简单格式:比较索引
- return props.modelValue === index;
- };
- const handleTabClick = (index, tab) => {
- if (isObjectTab(tab)) {
- // 对象格式:传递 value
- emit('update:modelValue', tab.value);
- emit('change', tab.value || tab.id, tab, index);
- } else {
- // 字符串/简单格式:传递索引
- emit('update:modelValue', index);
- emit('change', index, tab);
- }
- };
- </script>
- <style scoped lang="scss">
- .tabs-container {
- display: flex;
- align-items: center;
- gap: 8px;
-
- .tab-item {
- border-radius: 20px;
- text-align: center;
- }
-
- // 标签数量 <= 2 时的样式
- &.tabs-small {
- gap: 8px;
-
- .tab-item {
- padding: 5px 12px;
- }
- }
-
- // 默认样式
- &.tabs-type-default {
- justify-content: center;
- background: #fff;
- padding: 5px 0;
- .tab-item {
- padding: 4px 12px;
- color: rgba(0, 0, 0, 0.5);
- border: 1px solid transparent;
-
- &.active {
- background: rgba(33, 153, 248, 0.1);
- color: #2199F8;
- border: 1px solid #2199F8;
- }
- }
- }
-
- // 浅色样式(激活:浅蓝色背景+深蓝色文字,未激活:浅灰色背景+中灰色文字)
- &.tabs-type-light {
- .tab-item {
- background: #F7F8FA;
- color: #8B8B8B;
-
- &.active {
- background: rgba(33, 153, 248, 0.1);
- color: #2199F8;
- }
- }
- }
- }
- </style>
|