用vue实现tab切换
使用 Vue 实现 Tab 切换
基础实现(选项式 API)
在 Vue 中可以通过 v-for 和 v-show 或 v-if 结合数据绑定实现 Tab 切换功能。
模板部分
<div class="tabs">
<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>
脚本部分
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' }
]
}
}
}
样式部分
.tab-header button {
padding: 8px 16px;
cursor: pointer;
background: none;
border: none;
border-bottom: 2px solid transparent;
}
.tab-header button.active {
border-bottom-color: #42b983;
color: #42b983;
}
.tab-content {
margin-top: 16px;
}
组合式 API 实现
使用 Vue 3 的组合式 API 可以更简洁地实现相同功能。
<script setup>
import { ref } from 'vue'
const activeTab = ref(0)
const tabs = ref([
{ 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>
<template>
<!-- 模板部分与选项式API相同 -->
</template>
动态内容加载
如果需要动态加载 Tab 内容,可以结合异步组件或动态导入。
const tabs = ref([
{
title: 'User Profile',
component: defineAsyncComponent(() => import('./UserProfile.vue'))
},
{
title: 'Settings',
component: defineAsyncComponent(() => import('./Settings.vue'))
}
])
<component :is="tabs[activeTab].component" />
路由集成
将 Tab 切换与 Vue Router 集成可以实现基于 URL 的 Tab 状态管理。
const routes = [
{ path: '/', component: Home, children: [
{ path: 'tab1', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]}
]
<router-link to="/tab1">Tab 1</router-link>
<router-link to="/tab2">Tab 2</router-link>
<router-view></router-view>
可复用组件
创建一个可复用的 Tab 组件提高代码复用性。
<!-- TabContainer.vue -->
<template>
<div class="tab-container">
<slot name="header" :tabs="tabs" :activeTab="activeTab" :setActiveTab="setActiveTab"></slot>
<slot name="content" :activeTabContent="tabs[activeTab].content"></slot>
</div>
</template>
<script setup>
const props = defineProps({
tabs: { type: Array, required: true },
initialTab: { type: Number, default: 0 }
})
const activeTab = ref(props.initialTab)
const setActiveTab = (index) => { activeTab.value = index }
</script>
使用时:
<TabContainer :tabs="tabs">
<template #header="{ tabs, activeTab, setActiveTab }">
<!-- 自定义头部 -->
</template>
<template #content="{ activeTabContent }">
<!-- 自定义内容 -->
</template>
</TabContainer>






