vue实现一个tab栏
Vue 实现 Tab 栏
基础实现
创建 Tabs 和 Tab 组件,通过 v-model 控制当前激活的标签页。
Tabs.vue
<template>
<div class="tabs">
<div class="tabs-header">
<div
v-for="(tab, index) in tabs"
:key="index"
class="tab-header"
:class="{ active: index === modelValue }"
@click="selectTab(index)"
>
{{ tab.title }}
</div>
</div>
<div class="tabs-content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
modelValue: {
type: Number,
default: 0
}
},
data() {
return {
tabs: []
}
},
methods: {
selectTab(index) {
this.$emit('update:modelValue', index)
}
}
}
</script>
<style>
.tabs-header {
display: flex;
border-bottom: 1px solid #ccc;
}
.tab-header {
padding: 10px 20px;
cursor: pointer;
}
.tab-header.active {
border-bottom: 2px solid #42b983;
color: #42b983;
}
.tabs-content {
padding: 20px;
}
</style>
Tab.vue
<template>
<div v-show="isActive">
<slot></slot>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true
}
},
data() {
return {
isActive: false
}
},
mounted() {
this.$parent.tabs.push({
title: this.title
})
if (this.$parent.modelValue === this.$parent.tabs.length - 1) {
this.isActive = true
}
}
}
</script>
使用示例
<template>
<Tabs v-model="activeTab">
<Tab title="Tab 1">
Content for Tab 1
</Tab>
<Tab title="Tab 2">
Content for Tab 2
</Tab>
<Tab title="Tab 3">
Content for Tab 3
</Tab>
</Tabs>
</template>
<script>
import Tabs from './Tabs.vue'
import Tab from './Tab.vue'
export default {
components: { Tabs, Tab },
data() {
return {
activeTab: 0
}
}
}
</script>
进阶功能
添加动画效果
<transition name="fade" mode="out-in">
<div v-show="isActive" class="tab-content">
<slot></slot>
</div>
</transition>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
支持动态添加/删除标签页
// 在 Tabs.vue 中添加
watch: {
modelValue(newVal) {
this.tabs.forEach((tab, index) => {
this.$children[index].isActive = index === newVal
})
}
}
响应式设计
@media (max-width: 768px) {
.tabs-header {
flex-direction: column;
}
.tab-header {
width: 100%;
}
}
注意事项
- 确保
Tab组件始终是Tabs的直接子组件 - 动态添加/删除标签页时需要手动更新
tabs数组 - 对于复杂场景,可以考虑使用 Vuex 或 provide/inject 管理状态
- 可扩展支持图标、禁用状态等更多功能







