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. methods: {
  16. callback(key) {
  17. console.log(key);
  18. },
  19. },
  20. };
  21. </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
  8. defaultActiveKey="1"
  9. :tabPosition="mode"
  10. :style="{ height: '200px'}"
  11. @prevClick="callback"
  12. @nextClick="callback"
  13. >
  14. <a-tab-pane tab="Tab 1" key="1">Content of tab 1</a-tab-pane>
  15. <a-tab-pane tab="Tab 2" key="2">Content of tab 2</a-tab-pane>
  16. <a-tab-pane tab="Tab 3" key="3">Content of tab 3</a-tab-pane>
  17. <a-tab-pane tab="Tab 4" key="4">Content of tab 4</a-tab-pane>
  18. <a-tab-pane tab="Tab 5" key="5">Content of tab 5</a-tab-pane>
  19. <a-tab-pane tab="Tab 6" key="6">Content of tab 6</a-tab-pane>
  20. <a-tab-pane tab="Tab 7" key="7">Content of tab 7</a-tab-pane>
  21. <a-tab-pane tab="Tab 8" key="8">Content of tab 8</a-tab-pane>
  22. <a-tab-pane tab="Tab 9" key="9">Content of tab 9</a-tab-pane>
  23. <a-tab-pane tab="Tab 10" key="10">Content of tab 10</a-tab-pane>
  24. <a-tab-pane tab="Tab 11" key="11">Content of tab 11</a-tab-pane>
  25. </a-tabs>
  26. </div>
  27. </template>
  28. <script>
  29. export default {
  30. data() {
  31. return {
  32. mode: 'top',
  33. };
  34. },
  35. methods: {
  36. callback(val) {
  37. console.log(val);
  38. },
  39. },
  40. };
  41. </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. methods: {
  14. callback(key) {
  15. console.log(key);
  16. },
  17. },
  18. };
  19. </script>

Tabs 标签页 - 图9

新增和关闭页签

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

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