Tabs标签页 - 图1

Tabs 标签页

选项卡切换组件。

何时使用

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

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

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

代码演示

Tabs标签页 - 图2

基本用法

默认选中第一项。

  1. <template>
  2. <a-tabs v-model:activeKey="activeKey">
  3. <a-tab-pane key="1" tab="Tab 1">Content of Tab Pane 1</a-tab-pane>
  4. <a-tab-pane key="2" tab="Tab 2" force-render>Content of Tab Pane 2</a-tab-pane>
  5. <a-tab-pane key="3" tab="Tab 3">Content of Tab Pane 3</a-tab-pane>
  6. </a-tabs>
  7. </template>
  8. <script lang="ts">
  9. import { defineComponent, ref } from 'vue';
  10. export default defineComponent({
  11. setup() {
  12. return {
  13. activeKey: ref('1'),
  14. };
  15. },
  16. });
  17. </script>

Tabs标签页 - 图3

禁用

禁用某一项。

  1. <template>
  2. <a-tabs v-model:activeKey="activeKey">
  3. <a-tab-pane key="1" tab="Tab 1">Tab 1</a-tab-pane>
  4. <a-tab-pane key="2" tab="Tab 2" disabled>Tab 2</a-tab-pane>
  5. <a-tab-pane key="3" tab="Tab 3">Tab 3</a-tab-pane>
  6. </a-tabs>
  7. </template>
  8. <script lang="ts">
  9. import { defineComponent, ref } from 'vue';
  10. export default defineComponent({
  11. setup() {
  12. return {
  13. activeKey: ref('1'),
  14. };
  15. },
  16. });
  17. </script>

Tabs标签页 - 图4

图标

有图标的标签。

  1. <template>
  2. <a-tabs v-model:activeKey="activeKey">
  3. <a-tab-pane key="1">
  4. <template #tab>
  5. <span>
  6. <apple-outlined />
  7. Tab 1
  8. </span>
  9. </template>
  10. Tab 1
  11. </a-tab-pane>
  12. <a-tab-pane key="2">
  13. <template #tab>
  14. <span>
  15. <android-outlined />
  16. Tab 2
  17. </span>
  18. </template>
  19. Tab 2
  20. </a-tab-pane>
  21. </a-tabs>
  22. </template>
  23. <script lang="ts">
  24. import { AppleOutlined, AndroidOutlined } from '@ant-design/icons-vue';
  25. import { defineComponent, ref } from 'vue';
  26. export default defineComponent({
  27. setup() {
  28. return {
  29. activeKey: ref('1'),
  30. };
  31. },
  32. components: {
  33. AppleOutlined,
  34. AndroidOutlined,
  35. },
  36. });
  37. </script>

Tabs标签页 - 图5

滑动

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

  1. <template>
  2. <div style="width: 500px">
  3. <a-radio-group v-model:value="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. :tab-position="mode"
  9. :style="{ height: '200px' }"
  10. @prevClick="callback"
  11. @nextClick="callback"
  12. v-model:activeKey="activeKey"
  13. >
  14. <a-tab-pane v-for="i in 30" :key="i" :tab="`Tab-${i}`">Content of tab {{ i }}</a-tab-pane>
  15. </a-tabs>
  16. </div>
  17. </template>
  18. <script lang="ts">
  19. import { defineComponent, ref } from 'vue';
  20. export default defineComponent({
  21. setup() {
  22. const mode = ref('top');
  23. const activeKey = ref('1');
  24. const callback = (val: string) => {
  25. console.log(val);
  26. };
  27. return {
  28. mode,
  29. callback,
  30. activeKey,
  31. };
  32. },
  33. });
  34. </script>

Tabs标签页 - 图6

附加内容

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

  1. <template>
  2. <a-tabs v-model:activeKey="activeKey">
  3. <a-tab-pane key="1" tab="Tab 1">Content of tab 1</a-tab-pane>
  4. <a-tab-pane key="2" tab="Tab 2">Content of tab 2</a-tab-pane>
  5. <a-tab-pane key="3" tab="Tab 3">Content of tab 3</a-tab-pane>
  6. <template #tabBarExtraContent>
  7. <a-button>Extra Action</a-button>
  8. </template>
  9. </a-tabs>
  10. </template>
  11. <script lang="ts">
  12. import { defineComponent, ref } from 'vue';
  13. export default defineComponent({
  14. setup() {
  15. return {
  16. activeKey: ref('1'),
  17. };
  18. },
  19. });
  20. </script>

Tabs标签页 - 图7

大小

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

  1. <template>
  2. <div>
  3. <a-radio-group v-model:value="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 v-model:activeKey="activeKey" :size="size">
  9. <a-tab-pane key="1" tab="Tab 1">Content of tab 1</a-tab-pane>
  10. <a-tab-pane key="2" tab="Tab 2">Content of tab 2</a-tab-pane>
  11. <a-tab-pane key="3" tab="Tab 3">Content of tab 3</a-tab-pane>
  12. </a-tabs>
  13. </div>
  14. </template>
  15. <script lang="ts">
  16. import { defineComponent, ref } from 'vue';
  17. export default defineComponent({
  18. setup() {
  19. const size = ref('small');
  20. const activeKey = ref('1');
  21. return {
  22. size,
  23. activeKey,
  24. };
  25. },
  26. });
  27. </script>

Tabs标签页 - 图8

位置

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

  1. <template>
  2. <div style="width: 500px">
  3. <a-radio-group v-model:value="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 v-model:activeKey="activeKey" :tab-position="tabPosition">
  10. <a-tab-pane key="1" tab="Tab 1">Content of Tab 1</a-tab-pane>
  11. <a-tab-pane key="2" tab="Tab 2">Content of Tab 2</a-tab-pane>
  12. <a-tab-pane key="3" tab="Tab 3">Content of Tab 3</a-tab-pane>
  13. </a-tabs>
  14. </div>
  15. </template>
  16. <script lang="ts">
  17. import { defineComponent, ref } from 'vue';
  18. export default defineComponent({
  19. setup() {
  20. const tabPosition = ref('top');
  21. const activeKey = ref('1');
  22. return {
  23. tabPosition,
  24. activeKey,
  25. };
  26. },
  27. });
  28. </script>

Tabs标签页 - 图9

卡片式页签

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

  1. <template>
  2. <a-tabs type="card" v-model:activeKey="activeKey">
  3. <a-tab-pane key="1" tab="Tab 1">Content of Tab Pane 1</a-tab-pane>
  4. <a-tab-pane key="2" tab="Tab 2">Content of Tab Pane 2</a-tab-pane>
  5. <a-tab-pane key="3" tab="Tab 3">Content of Tab Pane 3</a-tab-pane>
  6. </a-tabs>
  7. </template>
  8. <script lang="ts">
  9. import { defineComponent, ref } from 'vue';
  10. export default defineComponent({
  11. setup() {
  12. return {
  13. activeKey: ref('1'),
  14. };
  15. },
  16. });
  17. </script>

Tabs标签页 - 图10

新增和关闭页签

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

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

Tabs标签页 - 图11

卡片式页签容器

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

  1. <template>
  2. <div class="card-container">
  3. <a-tabs v-model:activeKey="activeKey" type="card">
  4. <a-tab-pane key="1" tab="Tab Title 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 key="2" tab="Tab Title 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 key="3" tab="Tab Title 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 lang="ts">
  23. import { defineComponent, ref } from 'vue';
  24. export default defineComponent({
  25. setup() {
  26. return {
  27. activeKey: ref(1),
  28. };
  29. },
  30. });
  31. </script>
  32. <style>
  33. .card-container {
  34. background: #f5f5f5;
  35. overflow: hidden;
  36. padding: 24px;
  37. }
  38. .card-container > .ant-tabs-card > .ant-tabs-content {
  39. height: 120px;
  40. margin-top: -16px;
  41. }
  42. .card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
  43. background: #fff;
  44. padding: 16px;
  45. }
  46. .card-container > .ant-tabs-card > .ant-tabs-bar {
  47. border-color: #fff;
  48. }
  49. .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
  50. border-color: transparent;
  51. background: transparent;
  52. }
  53. .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
  54. border-color: #fff;
  55. background: #fff;
  56. }
  57. </style>

Tabs标签页 - 图12

自定义新增页签触发器

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

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

Tabs标签页 - 图13

自定义页签头

自定义页签头

  1. <template>
  2. <div>
  3. <a-tabs v-model:activeKey="activeKey">
  4. <a-tab-pane key="1" tab="Tab 1" style="height: 200px">Content of Tab Pane 1</a-tab-pane>
  5. <a-tab-pane key="2" tab="Tab 2" force-render>Content of Tab Pane 2</a-tab-pane>
  6. <a-tab-pane key="3" tab="Tab 3">Content of Tab Pane 3</a-tab-pane>
  7. <template #renderTabBar="{ DefaultTabBar, ...props }">
  8. <component
  9. :is="DefaultTabBar"
  10. v-bind="props"
  11. :style="{ zIndex: 1, background: '#fff', textAlign: 'right' }"
  12. />
  13. </template>
  14. </a-tabs>
  15. </div>
  16. </template>
  17. <script lang="ts">
  18. import { defineComponent, ref } from 'vue';
  19. export default defineComponent({
  20. setup() {
  21. return {
  22. activeKey: ref('1'),
  23. };
  24. },
  25. });
  26. </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