vue实现一个tab栏
Vue 实现 Tab 栏
基础实现(选项式 API)
<template>
<div class="tab-container">
<div class="tab-header">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="activeTab = index"
:class="{ 'active': activeTab === index }"
>
{{ tab.title }}
</button>
</div>
<div class="tab-content">
<div v-for="(tab, index) in tabs" :key="index" v-show="activeTab === index">
{{ tab.content }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
activeTab: 0,
tabs: [
{ title: 'Tab 1', content: 'Content for Tab 1' },
{ title: 'Tab 2', content: 'Content for Tab 2' },
{ title: 'Tab 3', content: 'Content for Tab 3' }
]
}
}
}
</script>
<style>
.tab-header {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.tab-header button {
padding: 8px 16px;
background: none;
border: 1px solid #ddd;
cursor: pointer;
}
.tab-header button.active {
background: #007bff;
color: white;
border-color: #007bff;
}
.tab-content {
border: 1px solid #ddd;
padding: 20px;
}
</style>
组合式 API 实现
<template>
<div class="tab-container">
<div class="tab-header">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="activeTab = index"
:class="{ 'active': activeTab === index }"
>
{{ tab.title }}
</button>
</div>
<div class="tab-content">
<component :is="tabs[activeTab].component" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Tab1Content from './Tab1Content.vue'
import Tab2Content from './Tab2Content.vue'
const activeTab = ref(0)
const tabs = [
{ title: 'Tab 1', component: Tab1Content },
{ title: 'Tab 2', component: Tab2Content }
]
</script>
动态组件实现
<template>
<div class="tab-container">
<div class="tab-header">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="activeTab = tab.component"
:class="{ 'active': activeTab === tab.component }"
>
{{ tab.title }}
</button>
</div>
<div class="tab-content">
<keep-alive>
<component :is="activeTab" />
</keep-alive>
</div>
</div>
</template>
<script setup>
import { ref, shallowRef } from 'vue'
import Tab1Content from './Tab1Content.vue'
import Tab2Content from './Tab2Content.vue'
const activeTab = shallowRef(Tab1Content)
const tabs = [
{ title: 'Tab 1', component: Tab1Content },
{ title: 'Tab 2', component: Tab2Content }
]
</script>
路由集成实现
<template>
<div class="tab-container">
<router-link
v-for="(tab, index) in tabs"
:key="index"
:to="tab.path"
custom
v-slot="{ navigate, isActive }"
>
<button
@click="navigate"
:class="{ 'active': isActive }"
>
{{ tab.title }}
</button>
</router-link>
<div class="tab-content">
<router-view />
</div>
</div>
</template>
<script setup>
const tabs = [
{ title: 'Tab 1', path: '/tab1' },
{ title: 'Tab 2', path: '/tab2' }
]
</script>
注意事项
- 使用
shallowRef 替代 ref 可以避免不必要的组件重新渲染
keep-alive 可以缓存组件状态,避免切换时重复渲染
- 路由集成时注意配置对应的路由规则
- 样式可以根据需求自定义,示例仅提供基础样式
