Tabs 标签页
分隔内容上有关联但属于不同类别的数据集合。
基础用法
基础的、简洁的标签页。
Tabs 组件提供了选项卡功能, 默认选中第一个标签页,你也可以通过 value 属性来指定当前选中的标签页。
基础用法
卡片风格:type="card"
边框卡片风格:type="border-card"
vue
<template>
<w-title>基础用法</w-title>
<w-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
<w-tab-pane label="待整改" name="first" />
<w-tab-pane label="已完成" name="second" />
<w-tab-pane label="已质控" name="third" />
</w-tabs>
<w-divider />
<w-title>卡片风格:type="card"</w-title>
<w-tabs
v-model="activeName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<w-tab-pane label="待整改" name="first" />
<w-tab-pane label="已完成" name="second" />
<w-tab-pane label="已质控" name="third" />
</w-tabs>
<w-divider />
<w-title>边框卡片风格:type="border-card"</w-title>
<w-tabs v-model="activeName" type="border-card">
<w-tab-pane label="待整改" name="first" />
<w-tab-pane label="已完成" name="second" />
<w-tab-pane label="已质控" name="third" />
</w-tabs>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { TabsPaneContext } from 'win-design-next'
const activeName = ref('first')
const handleClick = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event)
}
</script>
<style></style>
隐藏源代码
标签位置的设置
可以通过 tab-position 设置标签的位置
标签一共有四个方向的设置 tabPosition="left|right|top|bottom"
vue
<template>
<w-radio-group v-model="tabPosition" style="margin-bottom: 30px">
<w-radio-button value="top">top</w-radio-button>
<w-radio-button value="right">right</w-radio-button>
<w-radio-button value="bottom">bottom</w-radio-button>
<w-radio-button value="left">left</w-radio-button>
</w-radio-group>
<w-tabs :tab-position="tabPosition" style="height: 200px" class="demo-tabs">
<w-tab-pane label="待整改" name="first" />
<w-tab-pane label="已完成" name="second" />
<w-tab-pane label="已质控" name="third" />
</w-tabs>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { TabsInstance } from 'win-design-next'
const tabPosition = ref<TabsInstance['tabPosition']>('left')
</script>
<style>
.w3-tabs--right .w3-tabs__content,
.w3-tabs--left .w3-tabs__content {
height: 100%;
}
</style>
隐藏源代码
自定义标签页的内容
可以通过具名插槽来实现自定义标签页的内容
vue
<template>
<w-tabs type="border-card" class="demo-tabs">
<w-tab-pane>
<template #label>
<span class="custom-tabs-label">
<w-icon><date /></w-icon>
<span>待整改</span>
</span>
</template>
</w-tab-pane>
<w-tab-pane label="已完成" name="second" />
<w-tab-pane label="已质控" name="third" />
</w-tabs>
</template>
<script lang="ts" setup>
import { Date } from '@win-design-next/icons-vue'
</script>
<style>
.demo-tabs .custom-tabs-label {
display: flex;
align-items: center;
}
.demo-tabs .custom-tabs-label span {
margin-left: 8px;
}
</style>
隐藏源代码
动态增减标签页
增减标签页按钮只能在选项卡样式的标签页下使用
Tab 1 content
Tab 2 content
vue
<template>
<w-tabs
v-model="editableTabsValue"
type="card"
editable
class="demo-tabs"
@edit="handleTabsEdit"
>
<w-tab-pane
v-for="item in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
{{ item.content }}
</w-tab-pane>
</w-tabs>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { TabPaneName } from 'win-design-next'
let tabIndex = 2
const editableTabsValue = ref('2')
const editableTabs = ref([
{
title: 'Tab 1',
name: '1',
content: 'Tab 1 content',
},
{
title: 'Tab 2',
name: '2',
content: 'Tab 2 content',
},
])
const handleTabsEdit = (
targetName: TabPaneName | undefined,
action: 'remove' | 'add'
) => {
if (action === 'add') {
const newTabName = `${++tabIndex}`
editableTabs.value.push({
title: 'New Tab',
name: newTabName,
content: 'New Tab content',
})
editableTabsValue.value = newTabName
} else if (action === 'remove') {
const tabs = editableTabs.value
let activeName = editableTabsValue.value
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
const nextTab = tabs[index + 1] || tabs[index - 1]
if (nextTab) {
activeName = nextTab.name
}
}
})
}
editableTabsValue.value = activeName
editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
}
}
</script>
<style></style>
隐藏源代码
添加按钮自定义图标
Tab 1 content
Tab 2 content
vue
<template>
<w-tabs
v-model="editableTabsValue"
type="card"
class="demo-tabs"
editable
@edit="handleTabsEdit"
>
<template #add-icon>
<w-icon><Check /></w-icon>
</template>
<w-tab-pane
v-for="item in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
{{ item.content }}
</w-tab-pane>
</w-tabs>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Check } from '@win-design-next/icons-vue'
import type { TabPaneName } from 'win-design-next'
let tabIndex = 2
const editableTabsValue = ref('2')
const editableTabs = ref([
{
title: 'Tab 1',
name: '1',
content: 'Tab 1 content',
},
{
title: 'Tab 2',
name: '2',
content: 'Tab 2 content',
},
])
const handleTabsEdit = (
targetName: TabPaneName | undefined,
action: 'remove' | 'add'
) => {
if (action === 'add') {
const newTabName = `${++tabIndex}`
editableTabs.value.push({
title: 'New Tab',
name: newTabName,
content: 'New Tab content',
})
editableTabsValue.value = newTabName
} else if (action === 'remove') {
const tabs = editableTabs.value
let activeName = editableTabsValue.value
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
const nextTab = tabs[index + 1] || tabs[index - 1]
if (nextTab) {
activeName = nextTab.name
}
}
})
}
editableTabsValue.value = activeName
editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
}
}
</script>
<style></style>
隐藏源代码
增加标签页触发器自定义
Tab 1 content
Tab 2 content
vue
<template>
<div style="margin-bottom: 20px">
<w-button size="small" @click="addTab(editableTabsValue)">
add tab
</w-button>
</div>
<w-tabs
v-model="editableTabsValue"
type="card"
class="demo-tabs"
closable
@tab-remove="removeTab"
>
<w-tab-pane
v-for="item in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
{{ item.content }}
</w-tab-pane>
</w-tabs>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import type { TabPaneName } from 'win-design-next'
let tabIndex = 2
const editableTabsValue = ref('2')
const editableTabs = ref([
{
title: 'Tab 1',
name: '1',
content: 'Tab 1 content',
},
{
title: 'Tab 2',
name: '2',
content: 'Tab 2 content',
},
])
const addTab = (targetName: string) => {
const newTabName = `${++tabIndex}`
editableTabs.value.push({
title: 'New Tab',
name: newTabName,
content: 'New Tab content',
})
editableTabsValue.value = newTabName
}
const removeTab = (targetName: TabPaneName) => {
const tabs = editableTabs.value
let activeName = editableTabsValue.value
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
const nextTab = tabs[index + 1] || tabs[index - 1]
if (nextTab) {
activeName = nextTab.name
}
}
})
}
editableTabsValue.value = activeName
editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
}
</script>
<style></style>
隐藏源代码
Tabs API
Attributes
| 属性名 | 说明 | 类型 | Default |
|---|---|---|---|
| model-value / v-model | 绑定值,选中选项卡的 name,默认值是第一个 tab 的 name | string / number | — |
| type | 风格类型 | enum | '' |
| closable | 标签是否可关闭 | boolean | false |
| addable | 标签是否可增加 | boolean | false |
| editable | 标签是否同时可增加和关闭 | boolean | false |
| tab-position | 选项卡所在位置 | enum | top |
| stretch | 标签的宽度是否自撑开 | boolean | false |
| before-leave | 切换标签之前的钩子函数, 若返回 false 或者返回被 reject 的 Promise,则阻止切换。 | Function | () => true |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| tab-click | tab 被选中时触发 | Function |
| tab-change | activeName 改变时触发 | Function |
| tab-remove | 点击 tab 移除按钮时触发 | Function |
| tab-add | 点击 tab 新增按钮时触发 | Function |
| edit | 点击 tab 的新增或移除按钮后触发 | Function |
Slots
| 插槽名 | 说明 | 子标签 |
|---|---|---|
| default | 默认插槽 | Tab-pane |
| add-icon | 自定义添加按钮图标 | — |
Tab-pane API
Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 选项卡标题 | string | '' |
| disabled | 是否禁用 | boolean | false |
| name | 与选项卡绑定值 value 对应的标识符,表示选项卡别名。默认值是 tab 面板的序列号,如第一个 tab 是 0 | string / number | — |
| closable | 标签是否可关闭 | boolean | false |
| lazy | 标签是否延迟渲染 | boolean | false |
Slots
| 插槽名 | 说明 |
|---|---|
| default | Tab-pane 的内容 |
| label | Tab-pane 的标题内容 |
Copyright 2025 Winning Health 版权所有

