vue 实现tab切换
实现 Tab 切换的基本思路
在 Vue 中实现 Tab 切换通常通过动态绑定 class 或 v-show/v-if 控制内容显示,结合事件切换当前激活的 Tab。核心逻辑是维护一个状态(如 activeTab)来标识当前选中的 Tab。
方法一:使用 v-show 控制内容显示
通过 v-show 根据 activeTab 动态显示对应的内容区域,适合内容切换频繁的场景(无需频繁销毁组件)。
<template>
<div class="tab-container">
<div class="tab-header">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="activeTab = tab.id"
:class="{ 'active': activeTab === tab.id }"
>
{{ tab.title }}
</button>
</div>
<div class="tab-content">
<div v-show="activeTab === 'tab1'">内容 1</div>
<div v-show="activeTab === 'tab2'">内容 2</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
activeTab: 'tab1',
tabs: [
{ id: 'tab1', title: 'Tab 1' },
{ id: 'tab2', title: 'Tab 2' }
]
};
}
};
</script>
<style>
.tab-header button.active {
background-color: #42b983;
color: white;
}
</style>
方法二:使用 v-if 按需渲染
通过 v-if 条件渲染内容,适合内容较复杂或需要初始化性能优化的场景(切换时会销毁非活跃组件)。
<template>
<div class="tab-content">
<div v-if="activeTab === 'tab1'">内容 1</div>
<div v-else-if="activeTab === 'tab2'">内容 2</div>
</div>
</template>
方法三:动态组件 <component>
结合 Vue 的 <component> 和 :is 实现动态组件切换,适合每个 Tab 对应独立组件的情况。
<template>
<div>
<button @click="currentComponent = 'CompA'">Tab A</button>
<button @click="currentComponent = 'CompB'">Tab B</button>
<component :is="currentComponent" />
</div>
</template>
<script>
import CompA from './CompA.vue';
import CompB from './CompB.vue';
export default {
components: { CompA, CompB },
data() {
return {
currentComponent: 'CompA'
};
}
};
</script>
方法四:使用 Vue Router 实现路由级 Tab
通过路由参数或路径匹配实现 Tab 切换,适合需要 URL 同步或页面级 Tab 的场景。
// router.js
const routes = [
{ path: '/tab1', component: Tab1 },
{ path: '/tab2', component: Tab2 }
];
<template>
<router-link to="/tab1">Tab 1</router-link>
<router-link to="/tab2">Tab 2</router-link>
<router-view />
</template>
样式与交互优化
- 高亮当前 Tab:通过
:class绑定active类名。 - 动画效果:使用
<transition>包裹内容区域实现淡入淡出效果。 - 懒加载:结合
<keep-alive>缓存非活跃组件状态。
<transition name="fade" mode="out-in">
<keep-alive>
<component :is="currentComponent" />
</keep-alive>
</transition>
通过以上方法,可以灵活实现不同场景下的 Tab 切换需求。







