vue 实现tab页
Vue 实现 Tab 页的方法
使用动态组件 <component :is="">
通过 Vue 的 component 动态组件和 v-for 指令可以轻松实现 Tab 页功能。核心思路是利用 v-for 渲染 Tab 标题,并通过 v-model 或 v-bind 控制当前激活的 Tab。

<template>
<div>
<div class="tabs">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="currentTab = tab"
:class="{ active: currentTab === tab }"
>
{{ tab }}
</button>
</div>
<component :is="currentTabComponent"></component>
</div>
</template>
<script>
export default {
data() {
return {
tabs: ['Home', 'About', 'Contact'],
currentTab: 'Home'
};
},
computed: {
currentTabComponent() {
return this.currentTab.toLowerCase() + '-tab';
}
}
};
</script>
<style>
.active {
background-color: #42b983;
color: white;
}
</style>
使用 v-if 或 v-show 控制显示
另一种方法是直接通过 v-if 或 v-show 控制 Tab 内容的显示与隐藏。v-show 通过 CSS 的 display 属性切换,适合频繁切换的场景;v-if 会销毁和重建 DOM,适合不频繁切换的场景。

<template>
<div>
<div class="tabs">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="currentTab = tab.name"
:class="{ active: currentTab === tab.name }"
>
{{ tab.label }}
</button>
</div>
<div class="tab-content">
<div v-show="currentTab === 'home'">Home Content</div>
<div v-show="currentTab === 'about'">About Content</div>
<div v-show="currentTab === 'contact'">Contact Content</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tabs: [
{ name: 'home', label: 'Home' },
{ name: 'about', label: 'About' },
{ name: 'contact', label: 'Contact' }
],
currentTab: 'home'
};
}
};
</script>
使用 Vue Router 实现路由级 Tab
如果需要 Tab 页与 URL 同步,可以通过 Vue Router 实现路由级 Tab。每个 Tab 对应一个路由路径,适合复杂应用。
// router.js
const routes = [
{ path: '/', component: Home, name: 'home' },
{ path: '/about', component: About, name: 'about' },
{ path: '/contact', component: Contact, name: 'contact' }
];
<template>
<div>
<router-link
v-for="(tab, index) in tabs"
:key="index"
:to="{ name: tab.name }"
active-class="active"
>
{{ tab.label }}
</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
tabs: [
{ name: 'home', label: 'Home' },
{ name: 'about', label: 'About' },
{ name: 'contact', label: 'Contact' }
]
};
}
};
</script>
封装可复用的 Tab 组件
为了提高复用性,可以封装一个通用的 Tab 组件,通过插槽(Slots)传递内容。
<!-- Tabs.vue -->
<template>
<div>
<div class="tabs-header">
<button
v-for="(tab, index) in tabs"
:key="index"
@click="currentTab = tab.name"
:class="{ active: currentTab === tab.name }"
>
{{ tab.label }}
</button>
</div>
<div class="tabs-content">
<slot :name="currentTab"></slot>
</div>
</div>
</template>
<script>
export default {
props: {
tabs: Array,
initialTab: String
},
data() {
return {
currentTab: this.initialTab || this.tabs[0].name
};
}
};
</script>
<!-- Parent.vue -->
<template>
<Tabs :tabs="tabs" initialTab="home">
<template #home>Home Content</template>
<template #about>About Content</template>
<template #contact>Contact Content</template>
</Tabs>
</template>
<script>
import Tabs from './Tabs.vue';
export default {
components: { Tabs },
data() {
return {
tabs: [
{ name: 'home', label: 'Home' },
{ name: 'about', label: 'About' },
{ name: 'contact', label: 'Contact' }
]
};
}
};
</script>
注意事项
- 动态组件需提前注册或异步加载。
- 路由级 Tab 需确保路由配置正确。
- 封装组件时注意插槽命名和作用域。






