Tabs标签页
用于让用户在不同的视图中进行切换。
规则
- 标签数量,一般 2-4 个;其中,标签中的文案需要精简,一般 2-4 个字。
- 在 iOS 端的次级页面中,不建议使用左右滑动来切换 Tab,这个和 iOS 的左滑返回存在冲突,eg:详情页中 Tabs。
代码演示
基本用法
最简单的用法。
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-basic',
template: `
<Tabs
[page]="3"
[useOnPan]="true"
[swipeable]="true"
[activeTab]="index"
[tabBarActiveTextColor]="'#1890ff'"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="titleTemplate">
<ng-template #titleTemplate>
<Badge [text]="3">
<div>First Tab</div>
</Badge>
</ng-template>
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of first tab
</div>
</TabPane>
<TabPane [title]="titleTemplate1">
<ng-template #titleTemplate1>
<Badge [text]="'今日(20)'">
<div>Second Tab</div>
</Badge>
</ng-template>
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of second tab
</div>
</TabPane>
<TabPane [title]="titleTemplate2">
<ng-template #titleTemplate2>
<Badge [dot]="true">
<div>Third Tab</div>
</Badge>
</ng-template>
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of third tab
</div>
</TabPane>
</Tabs>
<WhiteSpace></WhiteSpace>
<Tabs
[page]="3"
[activeTab]="index"
[tabBarPosition]="'bottom'"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="'First Tab'">
<div
style="display: flex; height: 150px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of first tab
</div>
</TabPane>
<TabPane [title]="'Second Tab'">
<div
style="display: flex; height: 150px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of second tab
</div>
</TabPane>
<TabPane [title]="'Third Tab'">
<div
style="display: flex; height: 150px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of third tab
</div>
</TabPane>
</Tabs>
`,
styles: [
`
/deep/ .am-badge {
text-align: right;
}
`
]
})
export class DemoTabsBasicComponent {
flag = true;
index = 1;
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
selectCard(e) {
console.log(' ', JSON.stringify(e));
}
changeIndex() {
this.index = 0;
}
}
无动画
切换Tab标签页不带动画效果
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-noanim',
template: `
<Tabs
[page]="3"
[animated]="false"
[useOnPan]="false"
[activeTab]="index"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="'First Tab'">
<div
style="display: flex; height: 150px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of first tab
</div>
</TabPane>
<TabPane [title]="'Second Tab'">
<div
style="display: flex; height: 150px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of second tab
</div>
</TabPane>
<TabPane [title]="'Third Tab'">
<div
style="display: flex; height: 150px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of third tab
</div>
</TabPane>
</Tabs>
`,
styles: [
`
/deep/ .am-badge {
text-align: right;
}
`
]
})
export class DemoTabsNoanimComponent {
index = 0;
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
}
固定高度
固定外部容器高度
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-fixedheight',
template: `
<Tabs
style="height: 200px;"
[page]="3"
[activeTab]="index"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="'First Tab'">
<div
style="display: flex; align-items: center; justify-content: center; height: 250px; background-color: rgb(255, 255, 255);"
>
Content of first tab
</div>
</TabPane>
<TabPane [title]="'Second Tab'">
<div
style="display: flex; align-items: center; justify-content: center; height: 250px; background-color: rgb(255, 255, 255);"
>
Content of second tab
</div>
</TabPane>
<TabPane [title]="'Third Tab'">
<div
style="display: flex; align-items: center; justify-content: center; height: 250px; background-color: rgb(255, 255, 255);"
>
Content of third tab
</div>
</TabPane>
</Tabs>
`
})
export class DemoTabsFixedheightComponent {
index = 0;
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
}
动态创建
TabPane被动态创建
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-dynamic',
template: `
<Tabs
[page]="5"
[useOnPan]="true"
[swipeable]="true"
[activeTab]="activeTabIndex"
[tabBarActiveTextColor]="'#1890ff'"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane *ngFor="let tabListItem of tabList; let i = index" [title]="tabListItem.title">
<div
style="display: block; padding: 40px; text-align: center; align-items: center;justify-content: center;height: 150px;background-color: #fff"
>
<div>{{ tabListItem.content }}</div>
<div Button [type]="'primary'" (onClick)="onClick()">Add Pane +</div>
</div>
</TabPane>
</Tabs>
`,
styles: [
`
/deep/ .am-badge {
text-align: right;
}
`
]
})
export class DemoTabsDynamicComponent {
flag = true;
activeTabIndex = 0;
tabList: any[] = [
{
title: '1st Tab',
content: '1st Tab Content'
},
{
title: '2nd Tab',
content: '2nd Tab Content'
},
{
title: '3rd Tab',
content: '3rd Tab Content'
}
];
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
selectCard(e) {
console.log(' ', JSON.stringify(e));
}
changeIndex() {
this.activeTabIndex = 0;
}
onClick() {
this.tabList.push({
title: '' + (this.tabList.length + 1) + 'th Tab',
content: '' + (this.tabList.length + 1) + 'th Tab Content'
});
}
}
垂直样式
tabDirection为vertical
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-vertical',
template: `
<Tabs
style="height: 200px;"
[page]="3"
[activeTab]="index"
[tabBarPosition]="'left'"
[tabDirection]="'vertical'"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="'First Tab'">
<div
style="display: flex; height: 200px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of first tab
</div>
</TabPane>
<TabPane [title]="'Second Tab'">
<div
style="display: flex; height: 200px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of second tab
</div>
</TabPane>
<TabPane [title]="'Third Tab'">
<div
style="display: flex; height: 200px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of third tab
</div>
</TabPane>
</Tabs>
`,
styles: [
`
/deep/ .am-badge {
text-align: right;
}
`
]
})
export class DemoTabsVerticalComponent {
index = 0;
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
}
TabTitle固定尺寸
为TabTitle设置尺寸(单位:px)。
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-fixedtabtitlesize',
template: `
<Tabs
[page]="3"
[useOnPan]="true"
[swipeable]="true"
[activeTab]="index"
[tabTitleSize]="100"
[tabBarActiveTextColor]="'#1890ff'"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="titleTemplate">
<ng-template #titleTemplate>
<Badge [text]="3">
<div>First Tab</div>
</Badge>
</ng-template>
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of first tab
</div>
</TabPane>
<TabPane [title]="titleTemplate1">
<ng-template #titleTemplate1>
<Badge [text]="'今日(20)'">
<div>Second Tab</div>
</Badge>
</ng-template>
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of second tab
</div>
</TabPane>
</Tabs>
<WhiteSpace></WhiteSpace>
<Tabs
style="height: 200px;"
[page]="3"
[activeTab]="index"
[tabTitleSize]="40"
[tabBarPosition]="'left'"
[tabDirection]="'vertical'"
(onChange)="onChange($event)"
(onTabClick)="onTabClick($event)"
>
<TabPane [title]="'First Tab'">
<div
style="display: flex; height: 200px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of first tab
</div>
</TabPane>
<TabPane [title]="'Second Tab'">
<div
style="display: flex; height: 200px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of second tab
</div>
</TabPane>
<TabPane [title]="'Third Tab'">
<div
style="display: flex; height: 200px; width: 100%; background-color: white;align-items: center;justify-content: center;"
>
Content of third tab
</div>
</TabPane>
</Tabs>
`,
styles: [
`
/deep/ .am-badge {
text-align: right;
}
`
]
})
export class DemoTabsFixedtabtitlesizeComponent {
flag = true;
index = 1;
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
selectCard(e) {
console.log(' ', JSON.stringify(e));
}
changeIndex() {
this.index = 0;
}
}
自定义个数,超出界面宽度,多于5个标签
界面可见区域最多存在5个tab标签页,更多内容可以左右滑动标签页
import { Component } from '@angular/core';
@Component({
selector: 'demo-tabs-multitabs',
template: `
<Tabs
[page]="3"
[activeTab]="index"
[prerenderingSiblingsNumber]="2"
(onChange)="selectCard($event)"
(onTabClick)="selectCard($event)"
>
<TabPane [title]="'1st Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 1st tab
</div>
</TabPane>
<TabPane [title]="'2nd Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 2nd tab
</div>
</TabPane>
<TabPane [title]="'3rd Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 3rd tab
</div>
</TabPane>
<TabPane [title]="'4th Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 4th tab
</div>
</TabPane>
<TabPane [title]="'5th Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 5th tab
</div>
</TabPane>
<TabPane [title]="'6th Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 6th tab
</div>
</TabPane>
<TabPane [title]="'7th Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 7th tab
</div>
</TabPane>
<TabPane [title]="'8th Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 8th tab
</div>
</TabPane>
<TabPane [title]="'9th Tab'">
<div style="display: flex; align-items: center;justify-content: center;height: 150px;background-color: #fff">
Content of 9th tab
</div>
</TabPane>
</Tabs>
`,
styles: [
`
/deep/ .am-badge {
text-align: right;
}
`
]
})
export class DemoTabsMultitabsComponent {
index = 0;
onChange(item) {
console.log('onChange', item);
}
onTabClick(item) {
console.log('onTabClick', item);
}
selectCard(e) {
console.log(' ', JSON.stringify(e));
}
}
API
Tabs
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[activeTab] | 当前激活Tab索引 | number | 0 |
[tabBarPosition] | TabBar位置 | ‘top’ | ‘bottom’ | ‘left’ | ‘right’ | ‘top’ |
[page] | Tab分页尺寸 | number | 5 |
[swipeable] | 是否可以滑动内容切换 | boolean | true |
[useOnPan] | 使用跟手滚动 | boolean | true |
[animated] | 是否开启切换动画 | boolean | true |
[distanceToChangeTab] | 滑动切换阈值(宽度比例) | number | 0.3 |
[prerenderingSiblingsNumber] | 预加载两侧Tab数量, -1: 加载所有的Tab内容, 0: 仅加载当前tab内容, n: 预加载两侧n个Tab | number | -1 |
[tabDirection] | Tab方向 | ‘horizontal’ | ‘vertical’ | ‘horizontal’ |
[tabBarUnderlineStyle] | TabBar下划线样式 | object | - |
[tabBarBackgroundColor] | TabBar背景色 | string | - |
[tabBarActiveTextColor] | TabBar激活Tab文字颜色 | string | - |
[tabBarInactiveTextColor] | TabBar非激活Tab文字颜色 | string | - |
[tabBarTextStyle] | TabBar文字样式 | object | - |
[renderTabBar] | 替换TabBar的Tab | TemplateRef | - |
(onChange) | Tab变化时触发 | EventEmitter<{index: number}> | - |
(onTabClick) | Tab 被点击的回调 | EventEmitter<{index: number}> | - |
TabPane
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[title] | tab面板的标题 | string | TemplateRef | - |