纯Vue实现tab标签
Vue 实现 Tab 标签的步骤
基础结构
使用 Vue 的 v-for 和 v-show 或 v-if 实现动态渲染标签和内容。模板部分需包含标签头(tab headers)和内容区域(tab panels)。
<template>
<div class="tabs">
<div class="tab-headers">
<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>
数据与状态管理
在 Vue 组件的 data 中定义标签数据和控制状态的变量。tabs 数组存储标签信息,activeTab 记录当前选中标签的索引。
<script>
export default {
data() {
return {
tabs: [
{ title: '标签1', content: '内容1' },
{ title: '标签2', content: '内容2' },
{ title: '标签3', content: '内容3' }
],
activeTab: 0
};
}
};
</script>
样式优化
通过 CSS 高亮当前选中的标签,并优化布局。使用 flex 布局对齐标签头,为激活状态添加视觉反馈。
<style scoped>
.tab-headers {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.tab-headers button {
padding: 8px 16px;
border: none;
background: #eee;
cursor: pointer;
}
.tab-headers button.active {
background: #007bff;
color: white;
}
.tab-content {
border: 1px solid #ddd;
padding: 20px;
}
</style>
动态添加/删除标签
扩展功能支持动态增删标签。通过方法修改 tabs 数组,并确保 activeTab 逻辑正确。
methods: {
addTab() {
this.tabs.push({
title: `标签${this.tabs.length + 1}`,
content: `内容${this.tabs.length + 1}`
});
},
removeTab(index) {
this.tabs.splice(index, 1);
if (this.activeTab >= this.tabs.length) {
this.activeTab = Math.max(0, this.tabs.length - 1);
}
}
}
使用组件化
将标签封装为可复用组件,通过插槽(slots)或 props 传递内容。父组件通过 v-model 控制激活状态。
<!-- 子组件 TabContainer.vue -->
<template>
<div class="tabs">
<slot :activeTab="activeTab" :setActiveTab="setActiveTab"></slot>
</div>
</template>
<script>
export default {
props: ['initialTab'],
data() {
return { activeTab: this.initialTab || 0 };
},
methods: {
setActiveTab(index) {
this.activeTab = index;
}
}
};
</script>
父组件调用示例
<template>
<TabContainer v-model="currentTab">
<template #default="{ activeTab, setActiveTab }">
<div class="tab-headers">
<button
v-for="(tab, index) in tabs"
@click="setActiveTab(index)"
:class="{ active: activeTab === index }"
>
{{ tab.title }}
</button>
</div>
<div class="tab-content">
<div v-for="(tab, index) in tabs" v-show="activeTab === index">
{{ tab.content }}
</div>
</div>
</template>
</TabContainer>
</template>






