83 lines
1.9 KiB
Vue
83 lines
1.9 KiB
Vue
<template>
|
|
<div class="w-full h-full flex flex-col">
|
|
<!-- 标签页导航 -->
|
|
<div class="flex border-b border-gray-200 bg-white">
|
|
<button
|
|
v-for="(tab, index) in tabs"
|
|
:key="index"
|
|
@click="currentTab = index"
|
|
class="px-4 py-3 text-sm font-medium transition-colors duration-200"
|
|
:class="{
|
|
'text-blue-600 border-b-2 border-blue-600': currentTab === index,
|
|
'text-gray-500 hover:text-blue-500': currentTab !== index
|
|
}"
|
|
>
|
|
{{ tab.label }}
|
|
</button>
|
|
</div>
|
|
|
|
<!-- 标签页内容 -->
|
|
<div class="flex-grow p-4 bg-white rounded-b-lg min-h-0 flex flex-col">
|
|
<slot name="tab-content" :active-tab="currentTab">
|
|
<!-- 默认内容区域 -->
|
|
<div v-if="tabs[currentTab]?.component">
|
|
<component :is="tabs[currentTab].component" :key="currentTab" />
|
|
</div>
|
|
<div v-else-if="tabs[currentTab]?.content">
|
|
{{ tabs[currentTab].content }}
|
|
</div>
|
|
<div v-else>
|
|
<div class="flex items-center justify-center h-full min-h-[200px] text-gray-400">
|
|
请选择一个标签页
|
|
</div>
|
|
</div>
|
|
</slot>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, defineProps } from 'vue';
|
|
|
|
// 定义组件属性
|
|
const props = defineProps({
|
|
tabs: {
|
|
type: Array,
|
|
default: () => [
|
|
{
|
|
label: '首页',
|
|
content: '首页内容'
|
|
},
|
|
{
|
|
label: '设置',
|
|
content: '设置内容'
|
|
}
|
|
]
|
|
},
|
|
defaultTab: {
|
|
type: Number,
|
|
default: 0
|
|
}
|
|
});
|
|
|
|
// 当前激活的标签页
|
|
const currentTab = ref(props.defaultTab);
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 标签页容器样式 */
|
|
.tab-content {
|
|
animation: fadeIn 0.3s ease-in-out;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style> |