选项卡
选项卡是一种使用较少窗口空间显示更多信息的方法。本页通过 QTabs、QTab 和 QRouteTab 介绍选项卡选择部分。
该组件的一个常见用例是用于布局的页头/页脚。请参阅页面布局和页头 & 页脚页面以获取参考。
TIP
它可以很好的与 QTabPanels 组件搭配使用。
QTabs API
QTab API
QRouteTab API
用法
TIPS
- 当宽度大于容器宽度时,QTabs 可以水平滚动。相应地调整浏览器窗口大小,以查看此操作。
- 在桌面设备上,您会在两侧看到可点击的箭头图标。
- 在移动设备上,您可以使用手指滑动选项卡。
- 如果您想强制箭头图标在移动设备上可见,那么可以使用
mobile-arrows
属性。
WARNING
如果您不安装 Vue Router,QRouteTab 将不会也不能与 UMD 版本一起工作。
基础
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
v-model="tab"
class="text-teal"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
inline-label
class="bg-purple text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
no-caps
class="bg-orange text-white shadow-2"
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-tab name="movies" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
class="bg-teal text-yellow shadow-2"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
<q-tab name="movies" icon="movie" />
</q-tabs>
<q-tabs
v-model="tab"
inline-label
class="bg-primary text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
<q-tab name="photos" icon="photo" label="Photos" />
<q-tab name="videos" icon="slow_motion_video" label="Videos" />
<q-tab name="addressbook" icon="people" label="Address Book" />
</q-tabs>
</div>
</div>
</template>
外置,内置,隐藏箭头图标
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 300px">
<q-tabs
v-model="tab"
inline-label
outside-arrows
mobile-arrows
class="bg-primary text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
<q-tab name="photos" icon="photo" label="Photos" />
<q-tab name="videos" icon="slow_motion_video" label="Videos" />
<q-tab name="addressbook" icon="people" label="Address Book" />
</q-tabs>
<q-tabs
v-model="tab"
inline-label
mobile-arrows
class="bg-purple text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
<q-tab name="photos" icon="photo" label="Photos" />
<q-tab name="videos" icon="slow_motion_video" label="Videos" />
<q-tab name="addressbook" icon="people" label="Address Book" />
</q-tabs>
<q-tabs
v-model="tab"
no-caps
outside-arrows
mobile-arrows
class="bg-orange text-white shadow-2"
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-tab name="movies" label="Movies" />
</q-tabs>
</div>
</div>
</template>
垂直的
<template>
<div>
<q-splitter
v-model="splitterModel"
style="height: 250px"
>
<template v-slot:before>
<q-tabs
v-model="tab"
vertical
class="text-teal"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
</template>
<template v-slot:after>
<q-tab-panels
v-model="tab"
animated
swipeable
vertical
transition-prev="jump-up"
transition-next="jump-up"
>
<q-tab-panel name="mails">
<div class="text-h4 q-mb-md">Mails</div>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
</q-tab-panel>
<q-tab-panel name="alarms">
<div class="text-h4 q-mb-md">Alarms</div>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
</q-tab-panel>
<q-tab-panel name="movies">
<div class="text-h4 q-mb-md">Movies</div>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.</p>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</div>
</template>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
紧凑的
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
v-model="tab"
dense
class="bg-grey-2 text-teal"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
dense
no-caps
inline-label
class="bg-purple text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
dense
class="bg-orange text-white shadow-2"
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-tab name="movies" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
dense
class="bg-teal text-yellow shadow-2"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
<q-tab name="movies" icon="movie" />
</q-tabs>
</div>
</div>
</template>
独立的颜色
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 400px">
<q-tabs
v-model="tab"
narrow-indicator
dense
align="justify"
>
<q-tab class="text-purple" name="mails" icon="mail" label="Mails" />
<q-tab class="text-orange" name="alarms" icon="alarm" label="Alarms" />
<q-tab class="text-teal" name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
class="bg-grey-1"
dense
align="justify"
>
<q-tab class="text-orange" name="mails" icon="mail" label="Mails" />
<q-tab class="text-cyan" name="alarms" icon="alarm" label="Alarms" />
<q-tab class="text-red" name="movies" icon="movie" label="Movies" />
</q-tabs>
</div>
</div>
</template>
波纹动画
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 400px">
<q-tabs
v-model="tab"
narrow-indicator
dense
align="justify"
class="text-primary"
>
<q-tab :ripple="false" name="mails" icon="mail" label="Mails" />
<q-tab :ripple="false" name="alarms" icon="alarm" label="Alarms" />
<q-tab :ripple="false" name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
narrow-indicator
dense
align="justify"
class="text-purple"
>
<q-tab :ripple="{ color: 'orange' }" name="mails" icon="mail" label="Mails" />
<q-tab :ripple="{ color: 'orange' }" name="alarms" icon="alarm" label="Alarms" />
<q-tab :ripple="{ color: 'orange' }" name="movies" icon="movie" label="Movies" />
</q-tabs>
</div>
</div>
</template>
自定义指示器
在下面的示例中,请注意最后两个选项卡:指示器在顶部和禁用指示器。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
v-model="tab"
indicator-color="purple"
class="text-teal"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
<q-tab name="movies" icon="movie" />
</q-tabs>
<q-tabs
v-model="tab"
indicator-color="yellow"
class="bg-primary text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
narrow-indicator
class="bg-purple text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
inline-label
switch-indicator
indicator-color="primary"
class="bg-lime shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
indicator-color="transparent"
active-color="white"
class="bg-teal text-grey-5 shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
</div>
</div>
</template>
选项卡通知
有多种展示选项卡通知的方式:使用 QBadge,通过一个小点或者一个图标(可以是任何东西)。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
v-model="tab"
class="bg-primary text-white shadow-2"
>
<q-tab name="mails" icon="mail" label="Mails">
<q-badge color="red" floating>2</q-badge>
</q-tab>
<q-tab name="alarms" icon="alarm" label="Alarms">
<q-badge color="red" floating>10+</q-badge>
</q-tab>
<q-tab alert name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
class="bg-purple text-white shadow-2"
>
<q-tab alert="yellow" alert-icon="warning" name="mails" label="Mails" />
<q-tab alert alert-icon="event" label="Alarms" name="alarms" />
<q-tab alert="orange" alert-icon="announcement" name="movies" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
class="bg-yellow"
>
<q-tab name="mails" icon="mail" label="Mails">
<q-badge color="primary" text-color="white" floating>2</q-badge>
</q-tab>
<q-tab name="alarms" icon="alarm" label="Alarms">
<q-badge color="purple" text-color="white" floating>10+</q-badge>
</q-tab>
<q-tab alert name="movies" icon="movie" label="Movies" />
</q-tabs>
<q-tabs
v-model="tab"
class="bg-grey-3"
>
<q-tab alert="red" name="mails" icon="mail" label="Mails" />
<q-tab alert="purple" name="alarms" icon="alarm" label="Alarms" />
<q-tab alert="orange" name="movies" icon="movie" label="Movies" />
</q-tabs>
</div>
</div>
</template>
对齐
QTAB 是响应式的,当容器宽度(非窗口宽度)大于配置的断点时,align
属性将会生效(见下文)。出于演示的目的,下面的选项卡禁用了断点。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
v-model="tab"
dense
align="left"
class="bg-primary text-white shadow-2"
:breakpoint="0"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
</q-tabs>
<q-tabs
v-model="tab"
dense
align="center"
class="bg-primary text-white shadow-2"
:breakpoint="0"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
</q-tabs>
<q-tabs
v-model="tab"
dense
align="right"
class="bg-primary text-white shadow-2"
:breakpoint="0"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
</q-tabs>
<q-tabs
v-model="tab"
dense
align="justify"
class="bg-primary text-white shadow-2"
:breakpoint="0"
>
<q-tab name="mails" icon="mail" />
<q-tab name="alarms" icon="alarm" />
</q-tabs>
</div>
</div>
</template>
搭配下拉框
下面第四个选项卡中,如果窗口的宽度小于 1024px,那么 “Movies” 和 “Photos” 选项会被替换成一个 “More…” 下拉按钮。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
v-model="tab"
inline-label
class="bg-teal text-white shadow-2"
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-btn-dropdown auto-close stretch flat label="More...">
<q-list>
<q-item clickable @click="tab = 'movies'">
<q-item-section>Movies</q-item-section>
</q-item>
<q-item clickable @click="tab = 'photos'">
<q-item-section>Photos</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-tabs>
<q-tabs
v-model="tab"
inline-label
class="bg-yellow shadow-2"
>
<q-tab name="mails" label="Mails" icon="mail" />
<q-tab name="alarms" label="Alarms" icon="alarm" />
<q-btn-dropdown auto-close stretch flat icon="more" label="More...">
<q-list>
<q-item clickable @click="tab = 'movies'">
<q-item-section>Movies</q-item-section>
</q-item>
<q-item clickable @click="tab = 'photos'">
<q-item-section>Photos</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-tabs>
<q-tabs
v-model="tab"
class="bg-primary text-white shadow-2"
>
<q-tab name="mails" label="Mails" icon="mail" />
<q-tab name="alarms" label="Alarms" icon="alarm" />
<q-btn-dropdown auto-close stretch flat>
<template v-slot:label>
<div>
<div class="row justify-around items-center no-wrap">
<q-icon name="more" />
</div>
<div class="row items-center no-wrap">
More...
</div>
</div>
</template>
<q-list>
<q-item clickable @click="tab = 'movies'">
<q-item-section>Movies</q-item-section>
</q-item>
<q-item clickable @click="tab = 'photos'">
<q-item-section>Photos</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-tabs>
<q-tabs
v-model="tab"
inline-label
:breakpoint="0"
align="justify"
class="bg-purple text-white shadow-2"
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-tab v-if="$q.screen.gt.sm" name="movies" label="Movies" />
<q-tab v-if="$q.screen.gt.sm" name="photos" label="Photos" />
<q-btn-dropdown v-if="$q.screen.lt.md" auto-close stretch flat label="More...">
<q-list>
<q-item clickable @click="tab = 'movies'">
<q-item-section>Movies</q-item-section>
</q-item>
<q-item clickable @click="tab = 'photos'">
<q-item-section>Photos</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-tabs>
</div>
</div>
</template>
在 QToolbar 中
注意,我们需要声明 shrink
属性。默认情况下,QTabs 会尝试扩展到所有可用的水平空间,但是在下面的示例中,我们让其作为 QToolbar 的一个子元素,不希望它如此。
<template>
<div class="q-pa-md">
<q-toolbar class="bg-purple text-white shadow-2 rounded-borders">
<q-btn flat label="Homepage" />
<q-space />
<!--
notice shrink property since we are placing it
as child of QToolbar
-->
<q-tabs v-model="tab" shrink stretch>
<q-tab name="tab1" label="Tab 1" />
<q-tab name="tab2" label="Tab 2" />
<q-tab name="tab3" label="Tab 3" />
</q-tabs>
</q-toolbar>
</div>
</template>
动态更新
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-list>
<q-item v-for="item in allTabs" :key="item.tab.name" tag="label" dense v-ripple>
<q-item-section side>
<q-checkbox :model-value="item.selected" @update:model-value="status => { setTabSelected(item.tab, status) }" />
</q-item-section>
<q-item-section>
<q-item-label>{{ item.tab.label }}</q-item-label>
</q-item-section>
<q-item-section side>
<q-icon :name="item.tab.icon" />
</q-item-section>
</q-item>
</q-list>
<q-toolbar class="bg-purple text-white shadow-2 rounded-borders">
<q-btn flat label="Homepage" />
<q-space />
<!--
notice shrink property since we are placing it
as child of QToolbar
-->
<q-tabs
v-model="tab"
inline-label
shrink
stretch
>
<q-tab v-for="tab in tabs" :key="tab.name" v-bind="tab" />
</q-tabs>
</q-toolbar>
</div>
</div>
</template>
搭配 QTabsPanel
TIP
QTabPanels 也可以独立使用。它们不依赖于 QTabs 的存在。此外,它们可以放置在页面中的任何位置,而不仅仅是 QTabs 附近。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-card>
<q-tabs
v-model="tab"
dense
class="text-grey"
active-color="primary"
indicator-color="primary"
align="justify"
narrow-indicator
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-tab name="movies" label="Movies" />
</q-tabs>
<q-separator />
<q-tab-panels v-model="tab" animated>
<q-tab-panel name="mails">
<div class="text-h6">Mails</div>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</q-tab-panel>
<q-tab-panel name="alarms">
<div class="text-h6">Alarms</div>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</q-tab-panel>
<q-tab-panel name="movies">
<div class="text-h6">Movies</div>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</q-tab-panel>
</q-tab-panels>
</q-card>
<q-card>
<q-tab-panels v-model="tab" animated>
<q-tab-panel name="mails">
<div class="text-h6">Mails</div>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</q-tab-panel>
<q-tab-panel name="alarms">
<div class="text-h6">Alarms</div>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</q-tab-panel>
<q-tab-panel name="movies">
<div class="text-h6">Movies</div>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</q-tab-panel>
</q-tab-panels>
<q-separator />
<q-tabs
v-model="tab"
dense
class="bg-grey-3"
align="justify"
narrow-indicator
>
<q-tab name="mails" label="Mails" />
<q-tab name="alarms" label="Alarms" />
<q-tab name="movies" label="Movies" />
</q-tabs>
</q-card>
</div>
</div>
</template>
更多信息: 选项面板.
关联到 vue Router
您可以通过 QRouteTab
组件将选项卡与 vue Router 联系起来。这个组件继承了 QTab 的所有东西,此外,它还绑定了 router-link
中的属性,可以监听当前的应用程序路由,并在单击时触发路由行为。
<q-tabs>
<q-route-tab
icon="mail"
to="/mails"
exact
/>
<q-route-tab
icon="alarm"
to="/alarms"
exact
/>
</q-tabs>
WARNING
QRouteTab 是否变成选中态取决于您的应用程序的路由,而不是 v-model。所以 v-model 的初始值或者改变 v-model 的值不会改变您的应用的路由。
处理自定义的导航
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 600px">
<q-tabs
no-caps
class="bg-orange text-white shadow-2"
>
<q-route-tab :to="{ query: { tab: '1' } }" exact replace label="2s 后选中" @click="navDelay" />
<q-route-tab :to="{ query: { tab: '2' } }" exact replace label="不做任何事" @click="navCancel" />
<q-route-tab :to="{ query: { tab: '3' } }" exact replace label="导航去第二个选项卡" @click="navRedirect" />
<q-route-tab :to="{ query: { tab: '4' } }" exact replace label="立即导航" @click="navPass" />
</q-tabs>
</div>
</div>
</template>
<script>
export default {
methods: {
navDelay (e, go) {
e.preventDefault() // 取消默认的导航行为
// console.log('2s后触发导航')
setTimeout(() => {
// console.log('按照2秒前的承诺导航')
go()
}, 2000)
},
navCancel (e) {
e.preventDefault() //取消默认的导航行为
},
navRedirect (e, go) {
e.preventDefault() // 取消默认的导航行为
go({ query: { tab: '2', noScroll: true } })
},
navPass () {}
}
}
</script>