对于基于导航的选项卡(即会更改 URL 的选项卡),请改用 <b-nav>
组件。
基本用法
<div>
<b-tabs content-class="mt-3">
<b-tab title="First" active><p>I'm the first tab</p></b-tab>
<b-tab title="Second"><p>I'm the second tab</p></b-tab>
<b-tab title="Disabled" disabled><p>I'm a disabled tab!</p></b-tab>
</b-tabs>
</div>
提示:如果你动态添加或删除 <b-tab>
组件(即 v-if
或循环),你应为每个子 <b-tab>
组件提供一个唯一的 key
值。 key
属性是一个特殊的 Vue 属性,请参阅 https://vuejs.ac.cn/v2/api/#key。
卡片集成
选项卡支持与 Bootstrap 卡片集成。只需将 card
属性添加到 <b-tabs>
中,并将其放在 <b-card>
组件内即可。请注意,你应在 <b-card>
组件上添加 no-body
属性,以便正确装饰卡片标题并删除 card-body
引入的额外填充。
<div>
<b-card no-body>
<b-tabs card>
<b-tab title="Tab 1" active>
<b-card-text>Tab contents 1</b-card-text>
</b-tab>
<b-tab title="Tab 2">
<b-card-text>Tab contents 2</b-card-text>
</b-tab>
</b-tabs>
</b-card>
</div>
当 <b-tabs>
处于 card
模式时,每个 <b-tab>
子组件都会自动应用 card-body
类(此类提供选项卡内容周围的填充)。若要禁用 card-body
类,请在 <b-tab>
子组件上设置 no-body
属性。
<div>
<b-card no-body>
<b-tabs card>
<b-tab no-body title="Picture 1">
<b-card-img bottom src="https://picsum.photos/600/200/?image=21" alt="Image 21"></b-card-img>
<b-card-footer>Picture 1 footer</b-card-footer>
</b-tab>
<b-tab no-body title="Picture 2">
<b-card-img bottom src="https://picsum.photos/600/200/?image=25" alt="Image 25"></b-card-img>
<b-card-footer>Picture 2 footer</b-card-footer>
</b-tab>
<b-tab no-body title="Picture 3">
<b-card-img bottom src="https://picsum.photos/600/200/?image=26" alt="Image 26"></b-card-img>
<b-card-footer>Picture 3 footer</b-card-footer>
</b-tab>
<b-tab title="Text">
<b-card-title>This tab does not have the <code>no-body</code> prop set</b-card-title>
<b-card-text>
Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum
consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex
consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt
veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua
esse irure.
</b-card-text>
</b-tab>
</b-tabs>
</b-card>
</div>
注意:当 <b-tabs>
不处于 card
模式时,在 <b-tab>
上设置 no-body
属性不会产生任何影响(因为仅在 card
模式下才设置 card-body
类)。
有关卡片组件的更多详细信息,请参阅 卡片文档。
药片变体
默认情况下,选项卡使用 tabs
样式。只需将 pills
属性添加到 <b-tabs>
中即可获得药片样式变体。
<div>
<b-card no-body>
<b-tabs pills card>
<b-tab title="Tab 1" active><b-card-text>Tab contents 1</b-card-text></b-tab>
<b-tab title="Tab 2"><b-card-text>Tab contents 2</b-card-text></b-tab>
</b-tabs>
</b-card>
</div>
填充和对齐
强制 <b-tabs>
控件扩展为可用的全部宽度。
填充
若要使用选项卡控件按比例填充所有可用空间,请设置 fill
属性。请注意,所有水平空间都已占用,但并非每个控件都具有相同的宽度。
<div>
<b-tabs content-class="mt-3" fill>
<b-tab title="First" active><p>I'm the first tab</p></b-tab>
<b-tab title="Second"><p>I'm the second tab</p></b-tab>
<b-tab title="Very, very long title"><p>I'm the tab with the very, very long title</p></b-tab>
<b-tab title="Disabled" disabled><p>I'm a disabled tab!</p></b-tab>
</b-tabs>
</div>
对齐
对于等宽控件,请改用 justified
属性。所有水平空间都将被控件占用,但与上面使用 fill
不同,每个控件都将具有相同的宽度。
<div>
<b-tabs content-class="mt-3" justified>
<b-tab title="First" active><p>I'm the first tab</p></b-tab>
<b-tab title="Second"><p>I'm the second tab</p></b-tab>
<b-tab title="Very, very long title"><p>I'm the tab with the very, very long title</p></b-tab>
<b-tab title="Disabled" disabled><p>I'm a disabled tab!</p></b-tab>
</b-tabs>
</div>
对齐
若要对齐选项卡控件,请使用 align
属性。可用值包括 left
、center
和 right
。
<div>
<b-tabs content-class="mt-3" align="center">
<b-tab title="First" active><p>I'm the first tab</p></b-tab>
<b-tab title="Second"><p>I'm the second tab</p></b-tab>
<b-tab title="Disabled" disabled><p>I'm a disabled tab!</p></b-tab>
</b-tabs>
</div>
选项卡控件的底部位置
通过设置属性 end
,在视觉上将选项卡控件移动到底部。
<div>
<b-card no-body>
<b-tabs pills card end>
<b-tab title="Tab 1" active><b-card-text>Tab contents 1</b-card-text></b-tab>
<b-tab title="Tab 2"><b-card-text>Tab contents 2</b-card-text></b-tab>
</b-tabs>
</b-card>
</div>
注意事项
- 底部位置在视觉上最适合
pills
变体。在使用默认 tabs
变体时,您可能需要提供您自己的自定义样式类,因为 Bootstrap v4 CSS 假设选项卡始终放置在选项卡内容的顶部。 - 若要为底部放置的控件提供更好的用户体验,请确保每个选项卡窗格的内容高度相同,并且完全适合可见视口,否则用户需要向上滚动才能阅读选项卡内容的开头。
垂直选项卡
通过将 vertical
属性设置为 true
,将选项卡控件放置在左侧。垂直选项卡无论是否启用 card
模式,都可以正常工作。
<div>
<b-card no-body>
<b-tabs pills card vertical>
<b-tab title="Tab 1" active><b-card-text>Tab contents 1</b-card-text></b-tab>
<b-tab title="Tab 2"><b-card-text>Tab contents 2</b-card-text></b-tab>
<b-tab title="Tab 3"><b-card-text>Tab contents 3</b-card-text></b-tab>
</b-tabs>
</b-card>
</div>
通过设置 end
属性,在视觉上将选项卡控件移动到右侧
<div>
<b-card no-body>
<b-tabs pills card vertical end>
<b-tab title="Tab 1" active><b-card-text>Tab contents 1</b-card-text></b-tab>
<b-tab title="Tab 2"><b-card-text>Tab contents 2</b-card-text></b-tab>
<b-tab title="Tab 3"><b-card-text>Tab contents 3</b-card-text></b-tab>
</b-tabs>
</b-card>
</div>
垂直选项卡控件的宽度将扩展以适应选项卡标题的宽度。要控制宽度,请通过 nav-wrapper-class
属性设置一个 宽度实用程序类。您可以使用诸如 w-25
(25% 宽度)、w-50
(50% 宽度)等值,或诸如 col-2
、col-3
等列类。
<div>
<b-card no-body>
<b-tabs pills card vertical nav-wrapper-class="w-50">
<b-tab title="Tab 1" active><b-card-text>Tab contents 1</b-card-text></b-tab>
<b-tab title="Tab 2"><b-card-text>Tab contents 2</b-card-text></b-tab>
<b-tab title="Tab 3"><b-card-text>Tab contents 3</b-card-text></b-tab>
</b-tabs>
</b-card>
</div>
垂直放置在视觉上最适合 pills
变体。当使用默认 tabs
变体时,您可能希望提供您自己的自定义样式类,因为 Bootstrap v4 CSS 假设选项卡控件将始终放置在选项卡内容的顶部。
注意: 如果您的宽度比选项卡标题窄,可能会出现溢出文本。您可能需要额外的自定义样式。
活动类
要将类应用于当前活动控件或选项卡,请使用 active-nav-item-class
和 active-tab-class
属性。
<div>
<b-tabs
active-nav-item-class="font-weight-bold text-uppercase text-danger"
active-tab-class="font-weight-bold text-success"
content-class="mt-3"
>
<b-tab title="First" active><p>I'm the first tab</p></b-tab>
<b-tab title="Second"><p>I'm the second tab</p></b-tab>
<b-tab title="Disabled" disabled><p>I'm a disabled tab!</p></b-tab>
</b-tabs>
</div>
淡入动画
更改选项卡时默认启用淡入。可以使用 no-fade
属性禁用它。
添加无内容的选项卡
如果您想添加没有任何内容的额外选项卡,您可以将它们放在 tabs-start
或 tabs-end
插槽中
<div>
<b-tabs>
<template #tabs-end>
<b-nav-item href="#" role="presentation" @click="() => {}">Another tab</b-nav-item>
<li role="presentation" class="nav-item align-self-center">Plain text</li>
</template>
</b-tabs>
</div>
使用 tabs-start
插槽在内容选项卡按钮之前放置额外的选项卡按钮,并使用 tabs-end
插槽在内容选项卡按钮之后放置额外的选项卡按钮。
注意: 额外的(无内容)选项卡按钮应为 <b-nav-item>
或具有 <li>
根元素和 nav-item
类以进行适当的渲染和语义标记。
向选项卡标题添加自定义内容
如果您想向选项卡标题添加自定义内容,如 HTML 代码、图标或其他非交互式 Vue 组件,可以通过使用 <b-tab>
的 title
插槽来实现。
<div>
<b-tabs>
<b-tab active>
<template #title>
<b-spinner type="grow" small></b-spinner> I'm <i>custom</i> <strong>title</strong>
</template>
<p class="p-3">Tab contents 1</p>
</b-tab>
<b-tab>
<template #title>
<b-spinner type="border" small></b-spinner> Tab 2
</template>
<p class="p-3">Tab contents 2</p>
</b-tab>
</b-tabs>
</div>
不要 在标题插槽内放置交互式元素/组件。选项卡按钮是一个链接,根据 HTML5 规范,它不支持子交互式元素。
将自定义类应用到生成的导航标签或药片
标签选择器基于 Bootstrap v4 的 nav
标记(即 ul.nav > li.nav-item > a.nav-link
)。在某些情况下,您可能希望将类添加到 <li>
(nav-item)和/或 <a>
(nav-link)中,以按标签为基础。要执行此操作,只需将类名提供给 title-item-class
属性(对于 <li>
元素)或 title-link-class
属性(对于 <a>
元素)。值可以作为字符串或字符串数组传递。
注意: active
类会自动应用到活动标签 <a>
元素。您可能需要为此调整自定义类。
<template>
<div>
<b-card no-body>
<b-tabs v-model="tabIndex" card>
<b-tab title="Tab 1" :title-link-class="linkClass(0)">Tab contents 1</b-tab>
<b-tab title="Tab 2" :title-link-class="linkClass(1)">Tab contents 2</b-tab>
<b-tab title="Tab 3" :title-link-class="linkClass(2)">Tab contents 3</b-tab>
</b-tabs>
</b-card>
</div>
</template>
<script>
export default {
data() {
return {
tabIndex: 0
}
},
methods: {
linkClass(idx) {
if (this.tabIndex === idx) {
return ['bg-primary', 'text-light']
} else {
return ['bg-light', 'text-info']
}
}
}
}
</script>
延迟加载标签内容
有时,最好仅在激活标签时加载组件和数据,而不是在呈现 <b-tabs>
集时加载所有标签(和关联数据)。
可以通过 lazy
属性延迟加载各个 <b-tab>
组件,当设置该属性时,不会加载 <b-tab>
的内容,直到激活(显示)该内容,并且在标签停用(隐藏)时会卸载该内容。
<b-tabs content-class="mt-3">
<b-tab title="Regular tab"><b-alert show>I'm always mounted</b-alert></b-tab>
<b-tab title="Lazy tab" lazy><b-alert show>I'm lazy mounted!</b-alert></b-tab>
</b-tabs>
还可以通过在父 <b-tabs>
组件上设置 lazy
属性来使所有标签变为延迟加载。
<b-tabs content-class="mt-3" lazy>
<b-tab title="Tab 1"><b-alert show>I'm lazy mounted!</b-alert></b-tab>
<b-tab title="Tab 2"><b-alert show>I'm lazy mounted too!</b-alert></b-tab>
</b-tabs>
键盘导航
当标签按钮获得焦点时,默认情况下会启用键盘导航,以符合标签列表的 ARIA 规范。
按键 | 操作 |
向左 或 向上 | 激活上一个未禁用的标签 |
向右 或 向下 | 激活下一个未禁用的标签 |
Shift+向左 或 Shift+向上 | 激活第一个未禁用的标签 |
主页 | 激活第一个未禁用的标签 |
Shift+右 或 Shift+下 | 激活最后一个未禁用的选项卡 |
结束 | 激活最后一个未禁用的选项卡 |
制表符 | 将焦点移至活动选项卡内容 |
Shift+制表符 | 将焦点移至页面上的上一个控件 |
通过设置 prop no-key-nav
禁用键盘导航。现在,行为将默认使用 TAB 键进行常规浏览器导航。
按键 | 操作 |
制表符 | 移至页面上的下一个选项卡按钮或控件 |
Shift+制表符 | 移至页面上的上一个选项卡按钮或控件 |
Enter 或 空格 | 激活当前聚焦按钮的选项卡 |
以编程方式激活和停用选项卡
使用 <b-tabs>
v-model
通过将 v-model
设置为要显示的选项卡的索引(从零开始)来控制哪个选项卡处于活动状态(请参见下面的示例)。
或者,你可以在每个 <b-tab>
上使用 active
prop 和 .sync
修饰符来激活选项卡,或检测某个特定选项卡是否处于活动状态。
每个 <b-tab>
实例还提供了两种公开方法来激活或停用选项卡。这些方法分别是 .activate()
和 .deactivate()
。如果激活或停用失败(即某个选项卡已禁用或没有可用于激活的选项卡),则当前活动选项卡将保持活动状态,并且该方法将返回 false
。你需要引用 <b-tab>
才能使用这些方法。
防止激活 <b-tab>
要防止选项卡激活,只需在 <b-tab>
组件上设置 disabled
prop。
或者,你可以监听 activate-tab
事件,该事件提供了一个选项来防止选项卡激活。activate-tab
事件带有三个参数
newTabIndex
:要激活的选项卡的索引 prevTabIndex
:当前活动选项卡的索引 bvEvent
:BvEvent
对象。调用 bvEvent.preventDefault()
以防止 newTabIndex
被激活
出于辅助功能原因,在使用 activate-tab
事件防止选项卡激活时,你应为用户提供一些通知,说明该选项卡为何无法激活。建议在 <b-tab>
组件上使用 disabled
属性,而不是使用 activate-tab
事件(因为 disabled
对屏幕阅读器用户来说更直观)。
高级示例
使用 v-model
的外部控件
<template>
<div>
<b-card no-body>
<b-tabs v-model="tabIndex" small card>
<b-tab title="General">I'm the first fading tab</b-tab>
<b-tab title="Edit profile">
I'm the second tab
<b-card>I'm the card in tab</b-card>
</b-tab>
<b-tab title="Premium Plan" disabled>Sibzamini!</b-tab>
<b-tab title="Info">I'm the last tab</b-tab>
</b-tabs>
</b-card>
<div class="text-center">
<b-button-group class="mt-2">
<b-button @click="tabIndex--">Previous</b-button>
<b-button @click="tabIndex++">Next</b-button>
</b-button-group>
<div class="text-muted">Current Tab: {{ tabIndex }}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tabIndex: 1
}
}
}
</script>
动态选项卡 + tabs-end 插槽
<template>
<div>
<b-card no-body>
<b-tabs card>
<b-tab v-for="i in tabs" :key="'dyn-tab-' + i" :title="'Tab ' + i">
Tab contents {{ i }}
<b-button size="sm" variant="danger" class="float-right" @click="closeTab(i)">
Close tab
</b-button>
</b-tab>
<template #tabs-end>
<b-nav-item role="presentation" @click.prevent="newTab" href="#"><b>+</b></b-nav-item>
</template>
<template #empty>
<div class="text-center text-muted">
There are no open tabs<br>
Open a new tab using the <b>+</b> button above.
</div>
</template>
</b-tabs>
</b-card>
</div>
</template>
<script>
export default {
data() {
return {
tabs: [],
tabCounter: 0
}
},
methods: {
closeTab(x) {
for (let i = 0; i < this.tabs.length; i++) {
if (this.tabs[i] === x) {
this.tabs.splice(i, 1)
}
}
},
newTab() {
this.tabs.push(this.tabCounter++)
}
}
}
</script>