Tabs 标签页

选项卡切换组件。

何时使用

提供平级的区域将大块内容进行收纳和展现,保持界面整洁。

Ant Design 依次提供了三级选项卡,分别用于不同的场景。

  • 卡片式的页签,提供可关闭的样式,常用于容器顶部。
  • 标准线条式页签,用于容器内部的主功能切换,这是最常用的 Tabs。
  • RadioButton 可作为更次级的页签来使用。

代码演示

Tabs标签页 - 图1

基本用法

默认选中第一项。

  1. <template>
  2. <div>
  3. <a-tabs defaultActiveKey="1" @change="callback">
  4. <a-tab-pane tab="Tab 1" key="1">Content of Tab Pane 1</a-tab-pane>
  5. <a-tab-pane tab="Tab 2" key="2" forceRender>Content of Tab Pane 2</a-tab-pane>
  6. <a-tab-pane tab="Tab 3" key="3">Content of Tab Pane 3</a-tab-pane>
  7. </a-tabs>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. data () {
  13. return {
  14. }
  15. },
  16. methods: {
  17. callback (key) {
  18. console.log(key)
  19. },
  20. },
  21. }
  22. </script>

Tabs标签页 - 图2

禁用

禁用某一项。

  1. <template>
  2. <a-tabs defaultActiveKey="1">
  3. <a-tab-pane tab="Tab 1" key="1">Tab 1</a-tab-pane>
  4. <a-tab-pane tab="Tab 2" disabled key="2">Tab 2</a-tab-pane>
  5. <a-tab-pane tab="Tab 3" key="3">Tab 3</a-tab-pane>
  6. </a-tabs>
  7. </template>

Tabs标签页 - 图3

图标

有图标的标签。

  1. <template>
  2. <a-tabs defaultActiveKey="2">
  3. <a-tab-pane key="1">
  4. <span slot="tab">
  5. <a-icon type="apple" />
  6. Tab 1
  7. </span>
  8. Tab 1
  9. </a-tab-pane>
  10. <a-tab-pane key="2">
  11. <span slot="tab">
  12. <a-icon type="android" />
  13. Tab 2
  14. </span>
  15. Tab 2
  16. </a-tab-pane>
  17. </a-tabs>
  18. </template>

Tabs标签页 - 图4

滑动

可以左右、上下滑动,容纳更多标签。

  1. <template>
  2. <div style="width: 500px">
  3. <a-radio-group v-model="mode" :style="{ marginBottom: '8px' }">
  4. <a-radio-button value="top">Horizontal</a-radio-button>
  5. <a-radio-button value="left">Vertical</a-radio-button>
  6. </a-radio-group>
  7. <a-tabs defaultActiveKey="1" :tabPosition="mode" :style="{ height: '200px'}" @prevClick="callback" @nextClick="callback">
  8. <a-tab-pane tab="Tab 1" key="1">Content of tab 1</a-tab-pane>
  9. <a-tab-pane tab="Tab 2" key="2">Content of tab 2</a-tab-pane>
  10. <a-tab-pane tab="Tab 3" key="3">Content of tab 3</a-tab-pane>
  11. <a-tab-pane tab="Tab 4" key="4">Content of tab 4</a-tab-pane>
  12. <a-tab-pane tab="Tab 5" key="5">Content of tab 5</a-tab-pane>
  13. <a-tab-pane tab="Tab 6" key="6">Content of tab 6</a-tab-pane>
  14. <a-tab-pane tab="Tab 7" key="7">Content of tab 7</a-tab-pane>
  15. <a-tab-pane tab="Tab 8" key="8">Content of tab 8</a-tab-pane>
  16. <a-tab-pane tab="Tab 9" key="9">Content of tab 9</a-tab-pane>
  17. <a-tab-pane tab="Tab 10" key="10">Content of tab 10</a-tab-pane>
  18. <a-tab-pane tab="Tab 11" key="11">Content of tab 11</a-tab-pane>
  19. </a-tabs>
  20. </div>
  21. </template>
  22. <script>
  23. export default {
  24. data () {
  25. return {
  26. mode: 'top',
  27. }
  28. },
  29. methods: {
  30. callback (val) {
  31. console.log(val)
  32. },
  33. },
  34. }
  35. </script>

Tabs标签页 - 图5

附加内容

可以在页签右边添加附加操作。

  1. <template>
  2. <a-tabs>
  3. <a-tab-pane tab="Tab 1" key="1">Content of tab 1</a-tab-pane>
  4. <a-tab-pane tab="Tab 2" key="2">Content of tab 2</a-tab-pane>
  5. <a-tab-pane tab="Tab 3" key="3">Content of tab 3</a-tab-pane>
  6. <a-button slot="tabBarExtraContent">Extra Action</a-button>
  7. </a-tabs>
  8. </template>

Tabs标签页 - 图6

大小

大号页签用在页头区域,小号用在弹出框等较狭窄的容器内。

  1. <template>
  2. <div>
  3. <a-radio-group v-model="size" style="margin-bottom: 16px">
  4. <a-radio-button value="small">Small</a-radio-button>
  5. <a-radio-button value="default">Default</a-radio-button>
  6. <a-radio-button value="large">Large</a-radio-button>
  7. </a-radio-group>
  8. <a-tabs defaultActiveKey="2" :size="size">
  9. <a-tab-pane tab="Tab 1" key="1">Content of tab 1</a-tab-pane>
  10. <a-tab-pane tab="Tab 2" key="2">Content of tab 2</a-tab-pane>
  11. <a-tab-pane tab="Tab 3" key="3">Content of tab 3</a-tab-pane>
  12. </a-tabs>
  13. </div>
  14. </template>
  15. <script>
  16. export default {
  17. data () {
  18. return {
  19. size: 'small',
  20. }
  21. },
  22. }
  23. </script>

Tabs标签页 - 图7

位置

有四个位置,tabPosition="left|right|top|bottom"

  1. <template>
  2. <div style="width: 500px">
  3. <a-radio-group v-model="tabPosition" style="margin:8px">
  4. <a-radio-button value="top">top</a-radio-button>
  5. <a-radio-button value="bottom">bottom</a-radio-button>
  6. <a-radio-button value="left">left</a-radio-button>
  7. <a-radio-button value="right">right</a-radio-button>
  8. </a-radio-group>
  9. <a-tabs defaultActiveKey="1" :tabPosition="tabPosition">
  10. <a-tab-pane tab="Tab 1" key="1">Content of Tab 1</a-tab-pane>
  11. <a-tab-pane tab="Tab 2" key="2">Content of Tab 2</a-tab-pane>
  12. <a-tab-pane tab="Tab 3" key="3">Content of Tab 3</a-tab-pane>
  13. </a-tabs>
  14. </div>
  15. </template>
  16. <script>
  17. export default {
  18. data () {
  19. return {
  20. tabPosition: 'top',
  21. }
  22. },
  23. methods: {
  24. callback (val) {
  25. console.log(val)
  26. },
  27. },
  28. }
  29. </script>

Tabs标签页 - 图8

卡片式页签

另一种样式的页签,不提供对应的垂直样式。

  1. <template>
  2. <a-tabs @change="callback" type="card">
  3. <a-tab-pane tab="Tab 1" key="1">Content of Tab Pane 1</a-tab-pane>
  4. <a-tab-pane tab="Tab 2" key="2">Content of Tab Pane 2</a-tab-pane>
  5. <a-tab-pane tab="Tab 3" key="3">Content of Tab Pane 3</a-tab-pane>
  6. </a-tabs>
  7. </template>
  8. <script>
  9. export default {
  10. data () {
  11. return {
  12. }
  13. },
  14. methods: {
  15. callback (key) {
  16. console.log(key)
  17. },
  18. },
  19. }
  20. </script>

Tabs标签页 - 图9

新增和关闭页签

只有卡片样式的页签支持新增和关闭选项。使用 closable={false} 禁止关闭。

  1. <template>
  2. <a-tabs
  3. v-model="activeKey"
  4. type="editable-card"
  5. @edit="onEdit"
  6. >
  7. <a-tab-pane v-for="pane in panes" :tab="pane.title" :key="pane.key" :closable="pane.closable">
  8. {{pane.content}}
  9. </a-tab-pane>
  10. </a-tabs>
  11. </template>
  12. <script>
  13. export default {
  14. data () {
  15. const panes = [
  16. { title: 'Tab 1', content: 'Content of Tab 1', key: '1' },
  17. { title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
  18. { title: 'Tab 3', content: 'Content of Tab 3', key: '3', closable: false },
  19. ]
  20. return {
  21. activeKey: panes[0].key,
  22. panes,
  23. newTabIndex: 0,
  24. }
  25. },
  26. methods: {
  27. callback (key) {
  28. console.log(key)
  29. },
  30. onEdit (targetKey, action) {
  31. this[action](targetKey)
  32. },
  33. add () {
  34. const panes = this.panes
  35. const activeKey = `newTab${this.newTabIndex++}`
  36. panes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey })
  37. this.panes = panes
  38. this.activeKey = activeKey
  39. },
  40. remove (targetKey) {
  41. let activeKey = this.activeKey
  42. let lastIndex
  43. this.panes.forEach((pane, i) => {
  44. if (pane.key === targetKey) {
  45. lastIndex = i - 1
  46. }
  47. })
  48. const panes = this.panes.filter(pane => pane.key !== targetKey)
  49. if (lastIndex >= 0 && activeKey === targetKey) {
  50. activeKey = panes[lastIndex].key
  51. }
  52. this.panes = panes
  53. this.activeKey = activeKey
  54. },
  55. },
  56. }
  57. </script>

Tabs标签页 - 图10

卡片式页签容器

用于容器顶部,需要一点额外的样式覆盖。

  1. <template>
  2. <div class="card-container">
  3. <a-tabs type="card">
  4. <a-tab-pane tab="Tab Title 1" key="1">
  5. <p>Content of Tab Pane 1</p>
  6. <p>Content of Tab Pane 1</p>
  7. <p>Content of Tab Pane 1</p>
  8. </a-tab-pane>
  9. <a-tab-pane tab="Tab Title 2" key="2">
  10. <p>Content of Tab Pane 2</p>
  11. <p>Content of Tab Pane 2</p>
  12. <p>Content of Tab Pane 2</p>
  13. </a-tab-pane>
  14. <a-tab-pane tab="Tab Title 3" key="3">
  15. <p>Content of Tab Pane 3</p>
  16. <p>Content of Tab Pane 3</p>
  17. <p>Content of Tab Pane 3</p>
  18. </a-tab-pane>
  19. </a-tabs>
  20. </div>
  21. </template>
  22. <script>
  23. export default {
  24. data () {
  25. return {
  26. }
  27. },
  28. methods: {
  29. callback (key) {
  30. console.log(key)
  31. },
  32. },
  33. }
  34. </script>
  35. <style>
  36. .card-container {
  37. background: #F5F5F5;
  38. overflow: hidden;
  39. padding: 24px;
  40. }
  41. .card-container > .ant-tabs-card > .ant-tabs-content {
  42. height: 120px;
  43. margin-top: -16px;
  44. }
  45. .card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
  46. background: #fff;
  47. padding: 16px;
  48. }
  49. .card-container > .ant-tabs-card > .ant-tabs-bar {
  50. border-color: #fff;
  51. }
  52. .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
  53. border-color: transparent;
  54. background: transparent;
  55. }
  56. .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
  57. border-color: #fff;
  58. background: #fff;
  59. }
  60. </style>

Tabs标签页 - 图11

自定义新增页签触发器

隐藏默认的页签增加图标,给自定义触发器绑定事件。

  1. <template>
  2. <div>
  3. <div :style="{ marginBottom: '16px' }">
  4. <a-button @click="add">ADD</a-button>
  5. </div>
  6. <a-tabs
  7. hideAdd
  8. v-model="activeKey"
  9. type="editable-card"
  10. @edit="onEdit"
  11. >
  12. <a-tab-pane v-for="pane in panes" :tab="pane.title" :key="pane.key" :closable="pane.closable">
  13. {{pane.content}}
  14. </a-tab-pane>
  15. </a-tabs>
  16. </div>
  17. </template>
  18. <script>
  19. export default {
  20. data () {
  21. const panes = [
  22. { title: 'Tab 1', content: 'Content of Tab 1', key: '1' },
  23. { title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
  24. ]
  25. return {
  26. activeKey: panes[0].key,
  27. panes,
  28. newTabIndex: 0,
  29. }
  30. },
  31. methods: {
  32. callback (key) {
  33. console.log(key)
  34. },
  35. onEdit (targetKey, action) {
  36. this[action](targetKey)
  37. },
  38. add () {
  39. const panes = this.panes
  40. const activeKey = `newTab${this.newTabIndex++}`
  41. panes.push({ title: `New Tab ${activeKey}`, content: `Content of new Tab ${activeKey}`, key: activeKey })
  42. this.panes = panes
  43. this.activeKey = activeKey
  44. },
  45. remove (targetKey) {
  46. let activeKey = this.activeKey
  47. let lastIndex
  48. this.panes.forEach((pane, i) => {
  49. if (pane.key === targetKey) {
  50. lastIndex = i - 1
  51. }
  52. })
  53. const panes = this.panes.filter(pane => pane.key !== targetKey)
  54. if (lastIndex >= 0 && activeKey === targetKey) {
  55. activeKey = panes[lastIndex].key
  56. }
  57. this.panes = panes
  58. this.activeKey = activeKey
  59. },
  60. },
  61. }
  62. </script>

Tabs标签页 - 图12

自定义页签头

自定义页签头

  1. <template>
  2. <div>
  3. <a-tabs defaultActiveKey="1">
  4. <a-tab-pane tab="Tab 1" key="1" style="height: 200px">Content of Tab Pane 1</a-tab-pane>
  5. <a-tab-pane tab="Tab 2" key="2" forceRender>Content of Tab Pane 2</a-tab-pane>
  6. <a-tab-pane tab="Tab 3" key="3">Content of Tab Pane 3</a-tab-pane>
  7. <template slot="renderTabBar" slot-scope="props, DefaultTabBar">
  8. <component :is="DefaultTabBar" {...props} />
  9. </template>
  10. </a-tabs>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. data () {
  16. return {
  17. }
  18. },
  19. methods: {
  20. callback (key) {
  21. console.log(key)
  22. },
  23. },
  24. }
  25. </script>

API

Tabs

参数说明类型默认值
activeKey(v-model)当前激活 tab 面板的 keystring
animated是否使用动画切换 Tabs,在 tabPosition=top|bottom 时有效boolean | {inkBar:boolean, tabPane:boolean}true, 当 type="card" 时为 false
defaultActiveKey初始化选中面板的 key,如果没有设置 activeKeystring第一个面板
hideAdd是否隐藏加号图标,在 type="editable-card" 时有效booleanfalse
size大小,提供 large defaultsmall 三种大小string'default'
tabBarExtraContenttab bar 上额外的元素slot
tabBarStyletab bar 的样式对象object-
tabPosition页签位置,可选值有 top right bottom leftstring'top'
type页签的基本样式,可选 linecard editable-card 类型string'line'
tabBarGuttertabs 之间的间隙number

事件

事件名称说明回调参数
change切换面板的回调Function(activeKey) {}
edit新增和删除页签的回调,在 type="editable-card" 时有效(targetKey, action): void
nextClicknext 按钮被点击的回调Function
prevClickprev 按钮被点击的回调Function
tabClicktab 被点击的回调Function

Tabs.TabPane

参数说明类型默认值
forceRender被隐藏时是否渲染 DOM 结构booleanfalse
key对应 activeKeystring
tab选项卡头显示文字string|slot