Skip to content

Tabs 标签页

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

基础用法

基础的、简洁的标签页。

vue
<template>
  <NTabs v-model="activeTab">
    <NTabPane name="tab1" label="标签一">
      <p>内容一</p>
    </NTabPane>
    <NTabPane name="tab2" label="标签二">
      <p>内容二</p>
    </NTabPane>
    <NTabPane name="tab3" label="标签三">
      <p>内容三</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>

卡片风格

设置 type="card" 来启用卡片风格。

vue
<template>
  <NTabs v-model="activeTab" type="card">
    <NTabPane name="tab1" label="标签一">
      <p>内容一</p>
    </NTabPane>
    <NTabPane name="tab2" label="标签二">
      <p>内容二</p>
    </NTabPane>
    <NTabPane name="tab3" label="标签三">
      <p>内容三</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>

带边框的卡片

设置 type="border-card" 来启用带边框的卡片风格。

vue
<template>
  <NTabs v-model="activeTab" type="border-card">
    <NTabPane name="tab1" label="标签一">
      <p>内容一</p>
    </NTabPane>
    <NTabPane name="tab2" label="标签二">
      <p>内容二</p>
    </NTabPane>
    <NTabPane name="tab3" label="标签三">
      <p>内容三</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>

可关闭

设置 closable 属性来启用关闭功能。

vue
<template>
  <NTabs v-model="activeTab" type="card" closable @tab-remove="handleRemove">
    <NTabPane
      v-for="tab in tabs"
      :key="tab.name"
      :name="tab.name"
      :label="tab.label"
    >
      <p>{{ tab.content }}</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
const tabs = ref([
  { name: 'tab1', label: '标签一', content: '内容一' },
  { name: 'tab2', label: '标签二', content: '内容二' },
  { name: 'tab3', label: '标签三', content: '内容三' },
])

const handleRemove = (name) => {
  const index = tabs.value.findIndex(tab => tab.name === name)
  if (index !== -1) {
    tabs.value.splice(index, 1)
    if (activeTab.value === name) {
      activeTab.value = tabs.value[0]?.name || ''
    }
  }
}
</script>

标签位置

使用 tab-position 属性来设置标签的位置。

vue
<template>
  <div style="margin-bottom: 20px;">
    <NRadioGroup v-model="position">
      <NRadio value="top">顶部</NRadio>
      <NRadio value="right">右侧</NRadio>
      <NRadio value="bottom">底部</NRadio>
      <NRadio value="left">左侧</NRadio>
    </NRadioGroup>
  </div>
  <NTabs v-model="activeTab" :tabPosition="position">
    <NTabPane name="tab1" label="标签一">
      <p>内容一</p>
    </NTabPane>
    <NTabPane name="tab2" label="标签二">
      <p>内容二</p>
    </NTabPane>
    <NTabPane name="tab3" label="标签三">
      <p>内容三</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
const position = ref('top')
</script>

禁用标签

NTabPane 中设置 disabled 属性来禁用标签。

vue
<template>
  <NTabs v-model="activeTab">
    <NTabPane name="tab1" label="标签一">
      <p>内容一</p>
    </NTabPane>
    <NTabPane name="tab2" label="标签二" disabled>
      <p>内容二</p>
    </NTabPane>
    <NTabPane name="tab3" label="标签三">
      <p>内容三</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>

自定义标签

使用 label 插槽来自定义标签内容。

vue
<template>
  <NTabs v-model="activeTab">
    <NTabPane name="tab1">
      <template #label>
        <span>🔔 标签一</span>
      </template>
      <p>内容一</p>
    </NTabPane>
    <NTabPane name="tab2">
      <template #label>
        <span>📧 标签二</span>
      </template>
      <p>内容二</p>
    </NTabPane>
    <NTabPane name="tab3">
      <template #label>
        <span>⚙️ 标签三</span>
      </template>
      <p>内容三</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>

动态增减标签

结合卡片标签和可关闭功能,实现动态增减标签。

vue
<template>
  <div style="margin-bottom: 20px;">
    <NButton size="small" @click="addTab">添加标签</NButton>
  </div>
  <NTabs v-model="activeTab" type="card" closable @tab-remove="removeTab">
    <NTabPane
      v-for="tab in tabs"
      :key="tab.name"
      :name="tab.name"
      :label="tab.label"
    >
      <p>{{ tab.content }}</p>
    </NTabPane>
  </NTabs>
</template>

<script setup>
import { ref } from 'vue'
let tabIndex = 3
const activeTab = ref('tab1')
const tabs = ref([
  { name: 'tab1', label: '标签一', content: '内容一' },
  { name: 'tab2', label: '标签二', content: '内容二' },
  { name: 'tab3', label: '标签三', content: '内容三' },
])

const addTab = () => {
  tabIndex++
  const newTab = {
    name: `tab${tabIndex}`,
    label: `标签${tabIndex}`,
    content: `内容${tabIndex}`,
  }
  tabs.value.push(newTab)
  activeTab.value = newTab.name
}

const removeTab = (name) => {
  const index = tabs.value.findIndex(tab => tab.name === name)
  if (index !== -1) {
    tabs.value.splice(index, 1)
    if (activeTab.value === name) {
      activeTab.value = tabs.value[0]?.name || ''
    }
  }
}
</script>

Tabs API

Props

属性说明类型默认值
modelValue绑定值,选中选项卡的 namestring | number
type风格类型'' | 'card' | 'border-card'''
closable标签是否可关闭booleanfalse
tabPosition选项卡所在位置'top' | 'right' | 'bottom' | 'left''top'

Events

事件名说明类型
update:modelValue绑定值变化时触发(name: string | number) => void
tab-clicktab 被选中时触发(pane: any) => void
tab-remove点击 tab 移除按钮时触发(name: string | number) => void
tab-add点击 tab 新增按钮时触发() => void
edit点击 tab 的新增或移除按钮后触发(targetName: string | number | undefined, action: 'add' | 'remove') => void

TabPane API

Props

属性说明类型默认值
name选项卡的标识string | number
label选项卡的标题string
disabled是否禁用booleanfalse
closable标签是否可关闭boolean

Slots

插槽名说明
default选项卡的内容
label选项卡的标题内容