Appearance
Tabs 标签页
标签页组件用于在同一区域展示不同内容,支持多种样式和位置。
基础用法
基础的标签页用法,通过v-model绑定当前激活的标签索引。
Account
Password
Account
Make changes to your account here. Click save when you're done.
Password
Change your password here. After saving, you'll be logged out.
vue
<template>
<div class="demo-tabs-basic">
<Tabs v-model="activeTab" :tabs="tabs" @tab-click="handleTabClick" @update:modelValue="handleUpdateModelValue" @tab-close="handleClose">
<template #account>
<div class="tab-content">
<h3>Account</h3>
<p>Make changes to your account here. Click save when you're done.</p>
<div class="form-group">
<label>Name</label>
<Input type="text" value="Pedro Duarte" class="form-control" />
</div>
<div class="form-group">
<label>Username</label>
<Input type="text" value="@peduarte" class="form-control" />
</div>
<Button type="primary">保存</Button>
</div>
</template>
<template #password>
<div class="tab-content">
<h3>Password</h3>
<p>Change your password here. After saving, you'll be logged out.</p>
<div class="form-group">
<label>Current password</label>
<input type="password" class="form-control" />
</div>
<div class="form-group">
<label>New password</label>
<input type="password" class="form-control" />
</div>
<div class="form-group">
<label>Confirm new password</label>
<input type="password" class="form-control" />
</div>
<button class="btn btn-primary">Save password</button>
</div>
</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Account", name: "account" },
{ label: "Password", name: "password" },
];
const handleTabClick = (tab) => {
console.log("handleTabClick", tab);
};
const handleUpdateModelValue = (val) => {
console.log("handleUpdateModelValue", val);
};
const handleClose = (tab) => {
console.log("handleClose", tab);
};
</script>
<style scoped>
.demo-tabs-basic {
max-width: 600px;
margin: 0 auto;
}
.tab-content {
padding: 20px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
}
.form-group {
margin-bottom: 16px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
input {
width: 100%;
padding: 8px 12px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
box-sizing: border-box;
}
</style>不同类型
支持多种类型的标签页,包括primary、success、warning、danger和info。
Tab 1
Tab 2
Primary Tab Content
Secondary Tab Content
Tab 1
Tab 2
Success Tab Content
Secondary Tab Content
Tab 1
Tab 2
Warning Tab Content
Secondary Tab Content
Tab 1
Tab 2
Danger Tab Content
Secondary Tab Content
Tab 1
Tab 2
Info Tab Content
Secondary Tab Content
vue
<template>
<div class="demo-tabs-types">
<Tabs v-model="activeTab" :tabs="tabs" type="primary">
<template #tab1>Primary Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
type="success"
style="margin-top: 20px;"
>
<template #tab1>Success Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
type="warning"
style="margin-top: 20px;"
>
<template #tab1>Warning Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
type="danger"
style="margin-top: 20px;"
>
<template #tab1>Danger Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
type="info"
style="margin-top: 20px;"
>
<template #tab1>Info Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>不同尺寸
支持small、default和large三种尺寸。
Tab 1
Tab 2
Small Tab Content
Secondary Tab Content
Tab 1
Tab 2
Default Tab Content
Secondary Tab Content
Tab 1
Tab 2
Large Tab Content
Secondary Tab Content
vue
<template>
<div class="demo-tabs-sizes">
<Tabs v-model="activeTab" :tabs="tabs" size="small">
<template #tab1>Small Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
size="default"
style="margin-top: 20px;"
>
<template #tab1>Default Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
size="large"
style="margin-top: 20px;"
>
<template #tab1>Large Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>不同位置
标签页可以放置在top、bottom、left或right四个位置。
Tab 1
Tab 2
Top Tab Content
Secondary Tab Content
Tab 1
Tab 2
Bottom Tab Content
Secondary Tab Content
Tab 1
Tab 2
Left Tab Content
Secondary Tab Content
Tab 1
Tab 2
Right Tab Content
Secondary Tab Content
vue
<template>
<div class="demo-tabs-position">
<Tabs v-model="activeTab" :tabs="tabs" position="top">
<template #tab1>Top Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs
v-model="activeTab"
:tabs="tabs"
position="bottom"
style="margin-top: 20px;"
>
<template #tab1>Bottom Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<div style="display: flex; gap: 20px; margin-top: 20px;">
<Tabs v-model="activeTab" :tabs="tabs" position="left">
<template #tab1>Left Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
<Tabs v-model="activeTab" :tabs="tabs" position="right">
<template #tab1>Right Tab Content</template>
<template #tab2>Secondary Tab Content</template>
</Tabs>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>按钮样式
设置buttonStyle属性为true可以启用按钮样式的标签页,使标签看起来像按钮一样。
按钮 1
按钮 2
按钮 3
按钮样式标签页 1
这是按钮样式的标签页内容
按钮样式标签页 2
这是按钮样式的标签页内容
按钮样式标签页 3
这是按钮样式的标签页内容
vue
<template>
<div class="demo-tabs-button-style">
<Tabs v-model="buttonStyleTab" :tabs="buttonStyleTabs" buttonStyle="true">
<template #btn1>
<div class="tab-content">
<h3>按钮样式标签页 1</h3>
<p>这是按钮样式的标签页内容</p>
</div>
</template>
<template #btn2>
<div class="tab-content">
<h3>按钮样式标签页 2</h3>
<p>这是按钮样式的标签页内容</p>
</div>
</template>
<template #btn3>
<div class="tab-content">
<h3>按钮样式标签页 3</h3>
<p>这是按钮样式的标签页内容</p>
</div>
</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const buttonStyleTab = ref(0);
const buttonStyleTabs = ref([
{ label: "按钮 1", name: "btn1" },
{ label: "按钮 2", name: "btn2" },
{ label: "按钮 3", name: "btn3" },
]);
</script>
<style scoped>
.demo-tabs-button-style {
max-width: 600px;
margin: 0 auto;
}
.tab-content {
padding: 20px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
}
</style>按钮样式类型
按钮样式可以与不同类型结合使用:
主要
成功
警告
主要按钮样式
这是主要颜色的按钮样式标签页
主要按钮样式
这是主要颜色的按钮样式标签页
主要按钮样式
这是主要颜色的按钮样式标签页
vue
<template>
<div class="demo-tabs-button-style-types">
<Tabs
v-model="buttonStyleTypeTab"
:tabs="buttonStyleTypeTabs"
buttonStyle="true"
type="primary"
>
<template #primary1>
<div class="tab-content">
<h3>主要按钮样式</h3>
<p>这是主要颜色的按钮样式标签页</p>
</div>
</template>
<template #primary2>
<div class="tab-content">
<h3>主要按钮样式</h3>
<p>这是主要颜色的按钮样式标签页</p>
</div>
</template>
<template #primary3>
<div class="tab-content">
<h3>主要按钮样式</h3>
<p>这是主要颜色的按钮样式标签页</p>
</div>
</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const buttonStyleTypeTab = ref(0);
const buttonStyleTypeTabs = ref([
{ label: "主要", name: "primary1" },
{ label: "成功", name: "primary2" },
{ label: "警告", name: "primary3" },
]);
</script>
<style scoped>
.demo-tabs-button-style-types {
max-width: 600px;
margin: 0 auto;
}
.tab-content {
padding: 20px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
}
</style>自定义样式
背景与边框
设置tabsBg属性为true可以为标签页添加默认背景颜色。 设置borderLine属性为false可以移除标签页的底部边框。
Tab 1
Tab 2
带背景的标签页 1
这是带背景颜色的标签页内容
带背景的标签页 2
这是带背景颜色的标签页内容
vue
<template>
<Tabs
v-model="activeTab"
:tabs="tabs"
:tabsBg="true"
:borderLine="false"
type="primary"
>
<template #tab1>
<div class="tab-content">
<h3>带背景的标签页 1</h3>
<p>这是带背景颜色的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>带背景的标签页 2</h3>
<p>这是带背景颜色的标签页内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>自定义背景类
设置tabsBgClass属性可以自定义标签页的背景颜色类名。
Tab 1
Tab 2
自定义背景标签页 1
这是使用自定义背景类的标签页内容
自定义背景标签页 2
这是使用自定义背景类的标签页内容
vue
<template>
<Tabs
v-model="activeTab"
:tabs="tabs"
:tabsBgClass="'x-tabs_nav_bg'"
:borderLine="false"
>
<template #tab1>
<div class="tab-content">
<h3>自定义背景标签页 1</h3>
<p>这是使用自定义背景类的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>自定义背景标签页 2</h3>
<p>这是使用自定义背景类的标签页内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>
<style scoped>
.x-tabs_nav_bg {
background-color: var(--color-bg-hover-1);
}
</style>全宽标签
设置tabFull属性为true可以使标签页宽度平均分配并占满父容器。
Tab 1
Tab 2
全宽标签页 1
这是全宽标签页的内容
全宽标签页 2
这是全宽标签页的内容
vue
<template>
<Tabs v-model="activeTab" :tabs="tabs" :borderLine="false" :tabFull="true">
<template #tab1>
<div class="tab-content">
<h3>全宽标签页 1</h3>
<p>这是全宽标签页的内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>全宽标签页 2</h3>
<p>这是全宽标签页的内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>按钮样式标签
设置buttonStyle属性为true可以启用按钮样式的标签页,与borderLine属性结合使用可以创建更简洁的按钮效果。
Tab 1
Tab 2
按钮样式标签页 1
这是按钮样式的标签页内容
按钮样式标签页 2
这是按钮样式的标签页内容
vue
<template>
<Tabs
v-model="activeTab"
:buttonStyle="true"
:tabs="tabs"
:borderLine="false"
>
<template #tab1>
<div class="tab-content">
<h3>按钮样式标签页 1</h3>
<p>这是按钮样式的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>按钮样式标签页 2</h3>
<p>这是按钮样式的标签页内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>按钮样式与类型组合
按钮样式可以与type属性组合使用,创建不同颜色的按钮标签。
Tab 1
Tab 2
主色按钮标签页 1
这是主色按钮样式的标签页内容
主色按钮标签页 2
这是主色按钮样式的标签页内容
vue
<template>
<Tabs
v-model="activeTab"
:buttonStyle="true"
:tabs="tabs"
:borderLine="false"
type="primary"
>
<template #tab1>
<div class="tab-content">
<h3>主色按钮标签页 1</h3>
<p>这是主色按钮样式的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>主色按钮标签页 2</h3>
<p>这是主色按钮样式的标签页内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>文本按钮样式
设置buttonStyleText属性为true可以使标签页按钮样式为文本主题(仅边框和文字变色,背景保持透明)。
Tab 1
Tab 2
主色文本按钮标签页 1
这是主色文本按钮样式的标签页内容
主色文本按钮标签页 2
这是主色文本按钮样式的标签页内容
vue
<template>
<Tabs
v-model="activeTab"
:buttonStyle="true"
:buttonStyleText="true"
:tabs="tabs"
:borderLine="false"
type="primary"
>
<template #tab1>
<div class="tab-content">
<h3>主色文本按钮标签页 1</h3>
<p>这是主色文本按钮样式的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>主色文本按钮标签页 2</h3>
<p>这是主色文本按钮样式的标签页内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>全宽按钮标签
tabFull属性可以与按钮样式组合,创建全宽的按钮标签。
Tab 1
Tab 2
全宽按钮标签页 1
这是全宽按钮样式的标签页内容
全宽按钮标签页 2
这是全宽按钮样式的标签页内容
vue
<template>
<Tabs
v-model="activeTab"
:buttonStyle="true"
:tabs="tabs"
:borderLine="false"
:tabFull="true"
>
<template #tab1>
<div class="tab-content">
<h3>全宽按钮标签页 1</h3>
<p>这是全宽按钮样式的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>全宽按钮标签页 2</h3>
<p>这是全宽按钮样式的标签页内容</p>
</div>
</template>
</Tabs>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>自定义背景类名与全宽按钮标签
将 tabFull、tabsBgClass、buttonStyleText 结合使用
Tab 1
Tab 2
自定义背景类名标签页 1
这是自定义背景类名的标签页内容
自定义背景类名标签页 2
这是自定义背景类名的标签页内容
vue
<template>
<div class="demo-tabs-custom-bg-fullwidth">
<Tabs
v-model="activeTab"
:buttonStyle="true"
:buttonStyleText="true"
:tabs="tabs"
:borderLine="false"
:tabFull="true"
:tabsBg="true"
:tabsBgStyle="{
backgroundColor: 'var(--color-bg-hover-1)',
padding: '0.25rem',
}"
>
<template #tab1>
<div class="tab-content">
<h3>自定义背景类名标签页 1</h3>
<p>这是自定义背景类名的标签页内容</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>自定义背景类名标签页 2</h3>
<p>这是自定义背景类名的标签页内容</p>
</div>
</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2" },
];
</script>
<style scoped>
.x-tabs_nav_bg-1 {
padding: 0.25rem;
background-color: var(--color-bg-hover-1);
}
</style>禁用标签
可以禁用某些标签页。
Active
Disabled
Another Active
Active Tab Content
Disabled Tab Content
Another Active Tab Content
vue
<template>
<div class="demo-tabs-disabled">
<Tabs v-model="activeTab" :tabs="tabs">
<template #tab1>Active Tab Content</template>
<template #tab2>Disabled Tab Content</template>
<template #tab3>Another Active Tab Content</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const activeTab = ref(0);
const tabs = [
{ label: "Active", name: "tab1" },
{ label: "Disabled", name: "tab2", disabled: true },
{ label: "Another Active", name: "tab3" },
];
</script>部分标签可关闭
可以在标签配置中设置close属性来控制单个标签是否可关闭,而不是使用closable属性控制所有标签。
Tab 1
Tab 2 ×
Tab 3
Tab 4 ×
Tab 1
这个标签不可关闭
Tab 2
这个标签可关闭 (带close=true)
Tab 3
这个标签不可关闭
Tab 4
这个标签可关闭 (带close=true)
vue
<template>
<div class="demo-tabs-partial-closable">
<Tabs
v-model="partialClosableTab"
:tabs="partialClosableTabs"
@tab-close="handlePartialClose"
>
<template #tab1>
<div class="tab-content">
<h3>Tab 1</h3>
<p>这个标签不可关闭</p>
</div>
</template>
<template #tab2>
<div class="tab-content">
<h3>Tab 2</h3>
<p>这个标签可关闭 (带close=true)</p>
</div>
</template>
<template #tab3>
<div class="tab-content">
<h3>Tab 3</h3>
<p>这个标签不可关闭</p>
</div>
</template>
<template #tab4>
<div class="tab-content">
<h3>Tab 4</h3>
<p>这个标签可关闭 (带close=true)</p>
</div>
</template>
</Tabs>
</div>
</template>
<script setup>
import { ref } from "vue";
const partialClosableTab = ref(0);
const partialClosableTabs = ref([
{ label: "Tab 1", name: "tab1" },
{ label: "Tab 2", name: "tab2", close: true },
{ label: "Tab 3", name: "tab3" },
{ label: "Tab 4", name: "tab4", close: true },
]);
const handlePartialClose = (index) => {
// 防止关闭所有可关闭的标签页
const closableCount = partialClosableTabs.value.filter(
(tab) => tab.close
).length;
if (closableCount <= 1) {
// alert("至少需要保留一个可关闭的标签页");
return;
}
// 从tabs数组中移除对应标签
partialClosableTabs.value.splice(index, 1);
// 如果关闭的是当前激活的标签页,自动激活前一个标签页
if (partialClosableTab.value === index) {
partialClosableTab.value = Math.min(
index,
partialClosableTabs.value.length - 1
);
}
};
</script>
<style scoped>
.demo-tabs-partial-closable {
max-width: 600px;
margin: 0 auto;
}
.tab-content {
padding: 20px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
}
</style>API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue | 当前激活的标签索引 | number | 0 |
tabs | 标签配置数组 | Array<Tab> | [] |
position | 标签位置,可选值为 top、bottom、left、right | string | top |
type | 标签类型,可选值为 default、primary、success、warning、danger、info | string | default |
size | 标签尺寸,可选值为 small、default、large | string | default |
closable | 是否可关闭 | boolean | false |
buttonStyle | 是否使用按钮样式的标签页 | boolean | false |
tabsBg | 浅色背景 | boolean | |
tabsBgStyle | 自定义背景样式 | object | {} |
Tab 接口
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
label | 标签文本 | string | - |
name | 标签名称,对应插槽名称 | string | - |
disabled | 是否禁用 | boolean | false |
close | 是否可关闭(优先级高于 closable 属性) | boolean | false |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 标签切换时触发 | 当前标签索引 number |
tab-click | 标签点击时触发 | 当前标签索引 number |
tab-close | 标签关闭时触发(当closable为true时可用) | 当前标签索引 number |
Slots
| 插槽名 | 说明 |
|---|---|
[tab.name] | 对应标签的内容,tab.name为标签配置中的name属性值 |