Skip to content

Tabs 标签页

选项卡切换组件。

代码演示

基础用法

Content of Tab Pane 1
vue
<template>
  <a-tabs v-model:activeKey="activeKey">
    <a-tab-pane key="1" tab="Tab 1">Content of Tab Pane 1</a-tab-pane>
    <a-tab-pane key="2" tab="Tab 2" force-render>Content of Tab Pane 2</a-tab-pane>
    <a-tab-pane key="3" tab="Tab 3">Content of Tab Pane 3</a-tab-pane>
  </a-tabs>
</template>
<script setup>
import { ref } from 'vue';
const activeKey = ref('1');
</script>

禁用

禁用某一项。

Tab 1
vue
<template>
  <a-tabs v-model:activeKey="activeKey">
    <a-tab-pane key="1" tab="Tab 1">Tab 1</a-tab-pane>
    <a-tab-pane key="2" tab="Tab 2" disabled>Tab 2</a-tab-pane>
    <a-tab-pane key="3" tab="Tab 3">Tab 3</a-tab-pane>
  </a-tabs>
</template>
<script setup>
import { ref } from 'vue';
const activeKey = ref('1');
</script>

居中

标签居中展示。

Content of Tab Pane 1
vue
<template>
  <a-tabs v-model:activeKey="activeKey" centered>
    <a-tab-pane key="1" tab="Tab 1">Content of Tab Pane 1</a-tab-pane>
    <a-tab-pane key="2" tab="Tab 2" force-render>Content of Tab Pane 2</a-tab-pane>
    <a-tab-pane key="3" tab="Tab 3">Content of Tab Pane 3</a-tab-pane>
  </a-tabs>
</template>
<script setup>
import { ref } from 'vue';
const activeKey = ref('1');
</script>

滑动

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

vue
<template>
  <div>
    <a-radio-group v-model:value="mode" :style="{ marginBottom: '8px' }">
      <a-radio-button value="top">Horizontal</a-radio-button>
      <a-radio-button value="left">Vertical</a-radio-button>
    </a-radio-group>
    <a-tabs
      v-model:activeKey="activeKey3"
      :tab-position="mode"
      :style="{ height: '200px' }"
      @tabScroll="callback"
    >
      <a-tab-pane v-for="i in 30" :key="i" :tab="`Tab-${i}`">Content of tab {{ i }}</a-tab-pane>
    </a-tabs>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const mode = ref('top');
const activeKey = ref(1);
const callback = val => {
  console.log(val);
};
</script>

附加内容

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

Content of tab 1
vue
<template>
  <a-tabs v-model:activeKey="activeKey">
    <a-tab-pane key="1" tab="Tab 1">Content of tab 1</a-tab-pane>
    <a-tab-pane key="2" tab="Tab 2">Content of tab 2</a-tab-pane>
    <a-tab-pane key="3" tab="Tab 3">Content of tab 3</a-tab-pane>
    <template #leftExtra>
      <a-button class="tabs-extra-demo-button">Left Extra Action</a-button>
    </template>
    <template #rightExtra>
      <a-button>Right Extra Action</a-button>
    </template>
  </a-tabs>
</template>
<script setup>
import { ref } from 'vue';
const activeKey = ref('1');
</script>
<style scoped>
.tabs-extra-demo-button {
  margin-right: 16px;
}

.ant-row-rtl .tabs-extra-demo-button {
  margin-right: 0;
  margin-left: 16px;
}
</style>

大小

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

Content of tab 1
vue
<template>
  <div>
    <a-radio-group v-model:value="size" style="margin-bottom: 16px">
      <a-radio-button value="small">Small</a-radio-button>
      <a-radio-button value="default">Default</a-radio-button>
      <a-radio-button value="large">Large</a-radio-button>
    </a-radio-group>
    <a-tabs v-model:activeKey="activeKey" :size="size">
      <a-tab-pane key="1" tab="Tab 1">Content of tab 1</a-tab-pane>
      <a-tab-pane key="2" tab="Tab 2">Content of tab 2</a-tab-pane>
      <a-tab-pane key="3" tab="Tab 3">Content of tab 3</a-tab-pane>
    </a-tabs>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const size = ref('small');
const activeKey = ref('1');
</script>

位置

有四个位置,tabPosition="left|right|top|bottom。在移动端下,bottom|right 会自动切换成 top

Content of Tab 1
vue
<template>
  <a-radio-group v-model:value="tabPosition" style="margin: 8px">
    <a-radio-button value="top">top</a-radio-button>
    <a-radio-button value="bottom">bottom</a-radio-button>
    <a-radio-button value="left">left</a-radio-button>
    <a-radio-button value="right">right</a-radio-button>
  </a-radio-group>
  <a-tabs v-model:activeKey="activeKey" :tab-position="tabPosition" animated>
    <a-tab-pane key="1" tab="Tab 1">Content of Tab 1</a-tab-pane>
    <a-tab-pane key="2" tab="Tab 2">Content of Tab 2</a-tab-pane>
    <a-tab-pane key="3" tab="Tab 3">Content of Tab 3</a-tab-pane>
  </a-tabs>
</template>
<script setup>
import { ref } from 'vue';
const tabPosition = ref('top');
const activeKey = ref('1');
</script>

卡片式页签

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

Content of Tab Pane 1
vue
<template>
  <a-tabs v-model:activeKey="activeKey" type="card">
    <a-tab-pane key="1" tab="Tab 1">Content of Tab Pane 1</a-tab-pane>
    <a-tab-pane key="2" tab="Tab 2">Content of Tab Pane 2</a-tab-pane>
    <a-tab-pane key="3" tab="Tab 3">Content of Tab Pane 3</a-tab-pane>
  </a-tabs>
</template>
<script setup>
import { ref } from 'vue';
const activeKey = ref('1');
</script>

自定义新增页签触发器

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

Content of Tab Pane 1
vue
<template>
  <div>
    <div :style="{ marginBottom: '16px' }">
      <a-button @click="add">ADD</a-button>
    </div>
    <a-tabs v-model:activeKey="activeKey" hide-add type="editable-card" @edit="onEdit">
      <a-tab-pane v-for="pane in panes" :key="pane.key" :tab="pane.title" :closable="pane.closable">
        {{ pane.content }}
      </a-tab-pane>
    </a-tabs>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const panes = ref(
  new Array(2).fill(null).map((_, index) => {
    const id = String(index + 1);
    return {
      title: `Tab ${id}`,
      content: `Content of Tab Pane ${id}`,
      key: id,
    };
  }),
);
const activeKey = ref(panes.value[0].key);
const newTabIndex = ref(0);
const add = () => {
  activeKey.value = `newTab${newTabIndex.value++}`;
  panes.value.push({
    title: `New Tab ${activeKey.value}`,
    content: `Content of new Tab ${activeKey.value}`,
    key: activeKey.value,
  });
};
const remove = targetKey => {
  let lastIndex = 0;
  panes.value.forEach((pane, i) => {
    if (pane.key === targetKey) {
      lastIndex = i - 1;
    }
  });
  panes.value = panes.value.filter(pane => pane.key !== targetKey);
  if (panes.value.length && activeKey.value === targetKey) {
    if (lastIndex >= 0) {
      activeKey.value = panes.value[lastIndex].key;
    } else {
      activeKey.value = panes.value[0].key;
    }
  }
};
const onEdit = targetKey => {
  remove(targetKey);
};
</script>

API

Tabs

参数说明类型默认值
activeKey(v-model)当前激活 tab 面板的 keystring-
animated是否使用动画切换 Tabs,在 tabPosition="top" | "bottom" 时有效boolean | {inkBar:boolean, tabPane:boolean} true, 当 type="card" 时为false
centered标签居中展示booleanfalse
destroyInactiveTabPane被隐藏时是否销毁 DOM 结构booleanfalse
hideAdd是否隐藏加号图标,在 type="editable-card" 时有效booleanfalse
size大小,提供 large middle 和 small 三种大小stringmiddle
tabBarGuttertabs 之间的间隙number-
tabBarStyletab bar 的样式对象CSSProperties-
tabPosition页签位置,可选值有 top right bottom leftstringtop
type页签的基本样式,可选 line、card editable-card 类型stringline

Tabs 插槽

插槽名称说明参数
addIcon自定义添加按钮-
leftExtratab bar 上左侧额外的元素-
moreIcon自定义折叠 icon-
renderTabBar替换 TabBar,用于二次封装标签头{ DefaultTabBar }
rightExtratab bar 上右侧额外的元素-

Tabs 事件

事件名称说明回调参数
change切换面板的回调Function(activeKey) {}
edit新增和删除页签的回调,在 type="editable-card" 时有效(action === 'add' ? event : targetKey, action): void
tabClicktab 被点击的回调Function
tabScroll滚动 TabBar 时触发{ direction: 'left' | 'right' | 'top' | 'bottom' }

Tabs.TabPane

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

Tabs.TabPane 插槽

插槽名称说明参数
closeIcon自定义关闭图标,在 type="editable-card"时有效-
tab选项卡头显示文字-