Tabs 标签页

分隔内容上有关联但属于不同类别的数据集合。

基础用法

基础的、简洁的标签页。

Tabs 组件提供了选项卡功能, 默认选中第一个标签页,你也可以通过 value 属性来指定当前选中的标签页。

Tabs 标签页 - 图1

  1. <template>
  2. <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
  3. <el-tab-pane label="User" name="first">User</el-tab-pane>
  4. <el-tab-pane label="Config" name="second">Config</el-tab-pane>
  5. <el-tab-pane label="Role" name="third">Role</el-tab-pane>
  6. <el-tab-pane label="Task" name="fourth">Task</el-tab-pane>
  7. </el-tabs>
  8. </template>
  9. <script lang="ts" setup>
  10. import { ref } from 'vue'
  11. import type { TabsPaneContext } from 'element-plus'
  12. const activeName = ref('first')
  13. const handleClick = (tab: TabsPaneContext, event: Event) => {
  14. console.log(tab, event)
  15. }
  16. </script>
  17. <style>
  18. .demo-tabs > .el-tabs__content {
  19. padding: 32px;
  20. color: #6b778c;
  21. font-size: 32px;
  22. font-weight: 600;
  23. }
  24. </style>

卡片风格的标签

你可以设置具有卡片风格的标签。

只需要设置 type 属性为 card 就可以使选项卡改变为标签风格。

Tabs 标签页 - 图2

  1. <template>
  2. <el-tabs
  3. v-model="activeName"
  4. type="card"
  5. class="demo-tabs"
  6. @tab-click="handleClick"
  7. >
  8. <el-tab-pane label="User" name="first">User</el-tab-pane>
  9. <el-tab-pane label="Config" name="second">Config</el-tab-pane>
  10. <el-tab-pane label="Role" name="third">Role</el-tab-pane>
  11. <el-tab-pane label="Task" name="fourth">Task</el-tab-pane>
  12. </el-tabs>
  13. </template>
  14. <script lang="ts" setup>
  15. import { ref } from 'vue'
  16. import type { TabsPaneContext } from 'element-plus'
  17. const activeName = ref('first')
  18. const handleClick = (tab: TabsPaneContext, event: Event) => {
  19. console.log(tab, event)
  20. }
  21. </script>
  22. <style>
  23. .demo-tabs > .el-tabs__content {
  24. padding: 32px;
  25. color: #6b778c;
  26. font-size: 32px;
  27. font-weight: 600;
  28. }
  29. </style>

带有边框的卡片风格

你还可以设置标签页为带有边框的卡片

type 设置为 border-card

Tabs 标签页 - 图3

  1. <template>
  2. <el-tabs type="border-card">
  3. <el-tab-pane label="User">User</el-tab-pane>
  4. <el-tab-pane label="Config">Config</el-tab-pane>
  5. <el-tab-pane label="Role">Role</el-tab-pane>
  6. <el-tab-pane label="Task">Task</el-tab-pane>
  7. </el-tabs>
  8. </template>

标签位置的设置

可以通过 tab-position 设置标签的位置

标签一共有四个方向的设置 tabPosition="left|right|top|bottom"

Tabs 标签页 - 图4

  1. <template>
  2. <el-radio-group v-model="tabPosition" style="margin-bottom: 30px">
  3. <el-radio-button label="top">top</el-radio-button>
  4. <el-radio-button label="right">right</el-radio-button>
  5. <el-radio-button label="bottom">bottom</el-radio-button>
  6. <el-radio-button label="left">left</el-radio-button>
  7. </el-radio-group>
  8. <el-tabs :tab-position="tabPosition" style="height: 200px" class="demo-tabs">
  9. <el-tab-pane label="User">User</el-tab-pane>
  10. <el-tab-pane label="Config">Config</el-tab-pane>
  11. <el-tab-pane label="Role">Role</el-tab-pane>
  12. <el-tab-pane label="Task">Task</el-tab-pane>
  13. </el-tabs>
  14. </template>
  15. <script lang="ts" setup>
  16. import { ref } from 'vue'
  17. const tabPosition = ref('left')
  18. </script>
  19. <style>
  20. .demo-tabs > .el-tabs__content {
  21. padding: 32px;
  22. color: #6b778c;
  23. font-size: 32px;
  24. font-weight: 600;
  25. }
  26. .el-tabs--right .el-tabs__content,
  27. .el-tabs--left .el-tabs__content {
  28. height: 100%;
  29. }
  30. </style>

自定义标签页的内容

可以通过具名插槽来实现自定义标签页的内容

Tabs 标签页 - 图5

  1. <template>
  2. <el-tabs type="border-card" class="demo-tabs">
  3. <el-tab-pane>
  4. <template #label>
  5. <span class="custom-tabs-label">
  6. <el-icon><calendar /></el-icon>
  7. <span>Route</span>
  8. </span>
  9. </template>
  10. Route
  11. </el-tab-pane>
  12. <el-tab-pane label="Config">Config</el-tab-pane>
  13. <el-tab-pane label="Role">Role</el-tab-pane>
  14. <el-tab-pane label="Task">Task</el-tab-pane>
  15. </el-tabs>
  16. </template>
  17. <script lang="ts" setup>
  18. import { Calendar } from '@element-plus/icons-vue'
  19. </script>
  20. <style>
  21. .demo-tabs > .el-tabs__content {
  22. padding: 32px;
  23. color: #6b778c;
  24. font-size: 32px;
  25. font-weight: 600;
  26. }
  27. .demo-tabs .custom-tabs-label .el-icon {
  28. vertical-align: middle;
  29. }
  30. .demo-tabs .custom-tabs-label span {
  31. vertical-align: middle;
  32. margin-left: 4px;
  33. }
  34. </style>

动态增减标签页

增减标签页按钮只能在选项卡样式的标签页下使用

Tabs 标签页 - 图6

  1. <template>
  2. <el-tabs
  3. v-model="editableTabsValue"
  4. type="card"
  5. editable
  6. class="demo-tabs"
  7. @edit="handleTabsEdit"
  8. >
  9. <el-tab-pane
  10. v-for="item in editableTabs"
  11. :key="item.name"
  12. :label="item.title"
  13. :name="item.name"
  14. >
  15. {{ item.content }}
  16. </el-tab-pane>
  17. </el-tabs>
  18. </template>
  19. <script lang="ts" setup>
  20. import { ref } from 'vue'
  21. let tabIndex = 2
  22. const editableTabsValue = ref('2')
  23. const editableTabs = ref([
  24. {
  25. title: 'Tab 1',
  26. name: '1',
  27. content: 'Tab 1 content',
  28. },
  29. {
  30. title: 'Tab 2',
  31. name: '2',
  32. content: 'Tab 2 content',
  33. },
  34. ])
  35. const handleTabsEdit = (targetName: string, action: 'remove' | 'add') => {
  36. if (action === 'add') {
  37. const newTabName = `${++tabIndex}`
  38. editableTabs.value.push({
  39. title: 'New Tab',
  40. name: newTabName,
  41. content: 'New Tab content',
  42. })
  43. editableTabsValue.value = newTabName
  44. } else if (action === 'remove') {
  45. const tabs = editableTabs.value
  46. let activeName = editableTabsValue.value
  47. if (activeName === targetName) {
  48. tabs.forEach((tab, index) => {
  49. if (tab.name === targetName) {
  50. const nextTab = tabs[index + 1] || tabs[index - 1]
  51. if (nextTab) {
  52. activeName = nextTab.name
  53. }
  54. }
  55. })
  56. }
  57. editableTabsValue.value = activeName
  58. editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
  59. }
  60. }
  61. </script>
  62. <style>
  63. .demo-tabs > .el-tabs__content {
  64. padding: 32px;
  65. color: #6b778c;
  66. font-size: 32px;
  67. font-weight: 600;
  68. }
  69. </style>

自定义增加标签页触发器

Tabs 标签页 - 图7

  1. <template>
  2. <div style="margin-bottom: 20px">
  3. <el-button size="small" @click="addTab(editableTabsValue)">
  4. add tab
  5. </el-button>
  6. </div>
  7. <el-tabs
  8. v-model="editableTabsValue"
  9. type="card"
  10. class="demo-tabs"
  11. closable
  12. @tab-remove="removeTab"
  13. >
  14. <el-tab-pane
  15. v-for="item in editableTabs"
  16. :key="item.name"
  17. :label="item.title"
  18. :name="item.name"
  19. >
  20. {{ item.content }}
  21. </el-tab-pane>
  22. </el-tabs>
  23. </template>
  24. <script lang="ts" setup>
  25. import { ref } from 'vue'
  26. let tabIndex = 2
  27. const editableTabsValue = ref('2')
  28. const editableTabs = ref([
  29. {
  30. title: 'Tab 1',
  31. name: '1',
  32. content: 'Tab 1 content',
  33. },
  34. {
  35. title: 'Tab 2',
  36. name: '2',
  37. content: 'Tab 2 content',
  38. },
  39. ])
  40. const addTab = (targetName: string) => {
  41. const newTabName = `${++tabIndex}`
  42. editableTabs.value.push({
  43. title: 'New Tab',
  44. name: newTabName,
  45. content: 'New Tab content',
  46. })
  47. editableTabsValue.value = newTabName
  48. }
  49. const removeTab = (targetName: string) => {
  50. const tabs = editableTabs.value
  51. let activeName = editableTabsValue.value
  52. if (activeName === targetName) {
  53. tabs.forEach((tab, index) => {
  54. if (tab.name === targetName) {
  55. const nextTab = tabs[index + 1] || tabs[index - 1]
  56. if (nextTab) {
  57. activeName = nextTab.name
  58. }
  59. }
  60. })
  61. }
  62. editableTabsValue.value = activeName
  63. editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
  64. }
  65. </script>
  66. <style>
  67. .demo-tabs > .el-tabs__content {
  68. padding: 32px;
  69. color: #6b778c;
  70. font-size: 32px;
  71. font-weight: 600;
  72. }
  73. </style>

Tabs 属性

属性说明类型可选值默认值
model-value / v-model绑定值,选中选项卡的 namestring / number第一个选项卡的 name
type风格类型stringcard/border-card
closable标签是否可关闭booleanfalse
addable标签是否可增加booleanfalse
editable标签是否同时可增加和关闭booleanfalse
tab-position选项卡所在位置stringtop/right/bottom/lefttop
stretch标签的宽度是否自撑开boolean-false
before-leave切换标签之前的钩子函数, 若返回 false 或者返回被 reject 的 Promise,则阻止切换。Function(activeName, oldActiveName)

Tabs 事件

事件名说明回调参数
tab-clicktab 被选中时触发(pane: TabsPaneContext, ev: Event)
tab-changeactiveName 改变时触发(name: TabPanelName)
tab-remove点击 tab 移除按钮时触发(name: TabPanelName)
tab-add点击 tab 新增按钮时触发
edit点击 tab 的新增或移除按钮后触发(paneName: TabPanelName | undefined, action: ‘remove’ | ‘add’)

Tabs 插槽

插槽名说明子标签
-默认插槽Tab-pane

Tab-pane 属性

属性说明类型可选值默认值
label选项卡标题string
disabled是否禁用booleanfalse
name与选项卡绑定值 value 对应的标识符,表示选项卡别名string / number该选项卡在选项卡列表中的序数值,第一个选项卡为 ‘0’
closable标签是否可关闭booleanfalse
lazy标签是否延迟渲染booleanfalse

Tab-pane 插槽

插槽名说明
-Tab-pane 的内容
labelTab-pane 的标题内容

源代码

组件 Tabs 标签页 - 图8 文档 Tabs 标签页 - 图9

贡献者

Tabs 标签页 - 图10 三咲智子

Tabs 标签页 - 图11 云游君

Tabs 标签页 - 图12 JeremyWuuuuu

Tabs 标签页 - 图13 qiang

Tabs 标签页 - 图14 啝裳

Tabs 标签页 - 图15 Chen

Tabs 标签页 - 图16 Aex

Tabs 标签页 - 图17 LIUCHAO

Tabs 标签页 - 图18 Xc

Tabs 标签页 - 图19 Delyan Haralanov

Tabs 标签页 - 图20 류한경

Tabs 标签页 - 图21 on the field of hope

Tabs 标签页 - 图22 xiahouwei

Tabs 标签页 - 图23 bqy_fe

Tabs 标签页 - 图24 blackie

Tabs 标签页 - 图25 btea

Tabs 标签页 - 图26 Hefty

Tabs 标签页 - 图27 Zapic

Tabs 标签页 - 图28 周毓杰 (Oliver Zhou)

Tabs 标签页 - 图29 SongWuKong

Tabs 标签页 - 图30 Satrong

Tabs 标签页 - 图31 msidolphin

Tabs 标签页 - 图32 Hades-li

Tabs 标签页 - 图33 长喆

Tabs 标签页 - 图34 Linmj