内容组之间进行导航切换。当前内容需要分成同层级结构的组,进行内容切换展示,用在表单或者标准列表界面的顶部。
目前一个页面中仅支持使用一次 Tabs 组件。
在基础库 2.x 版本下,内嵌 scroll-view 产生 scroll-view 无法滚动的情况,建议 scroll-view 阻止 touch 事件冒泡:catchTouchStart、catchTouchMove。
Tabs 内部使用 transform 样式以进行轮播,会导致内嵌弹层显示问题,建议内部不嵌套包含弹层的组件或者使用 fallback 属性,以自己实现简单版的“轮播”,详见下方 fallback 的 demo。
属性
Tabs
属性 | 类型 | 必填 | 默认值 | 说明 |
adjustHeight | string | 否 | 'current' | 自动以指定滑块的高度为整个容器的高度。 |
activeClass | string | 否 | '' | swiper-item 可见时的 class。 |
animation | boolean | 否 | false | 是否有过渡动画。 |
className | string | 否 | - | 类名 |
easingFunction | string | 否 | 'default' | 切换缓动动画类型 |
index | number | 否 | 0 | 当前激活的索引。 |
nextMargin | string | 否 | '0px' | 后边距,单位 px,1.9.0 版本暂时只支持水平方向。 |
plus | string | slot | 否 | - | 右上角操作按钮,自定义节点 |
previousMargin | string | 否 | '0px' | 前边距,单位 px,1.9.0 版本暂时只支持水平方向。 |
snapToEdge | boolean | 否 | false | 当 swiper-item 个数大于等于 2,关闭 circular 并且开启 previous-margin 或 next-margin 时,可以指定这个边距是否应用到第一个、最后一个元素。 |
sticky | boolean | 否 | false | 是否支持吸顶 |
swipeRatio | number | 否 | 0.2 | 用户左右滑动手势触发切换的阈值,当滑动距离超过阈值时进行 swiper-item 切换。 |
swipeSpeed | number | 否 | 0.05 | 用户左右滑动手势对应的滑动距离,数值越小则需要用户手势相同位移下 swiper-item 位移越小。 |
swipeable | boolean | 否 | false | 是否支持手势切换。 |
title | slot-scope | 否 | - | 自定义 tab 标题样式,仅在 type 为 basis 时可用。 |
touchAngle | number | 否 | 45 | 用户左右滑动手势生效的滑动角度。角度根据 touchstart 事件和首次 touchmove 事件的坐标计算得出。数值越小越对用户的滑动方向准确度要求越高。 |
type | 'basis' | 'capsule' | 'mixin' | 否 | 'basis' | 类型
|
TabItem
属性 | 类型 | 必填 | 默认值 | 说明 |
tab | {title: string; subTitle?: string; badge?: number; disabled?: boolean}[] | 是 | - | 每一项 tab 内容 |
className | string | 否 | - | 类名 |
事件
事件名 | 说明 | 类型 |
onChange | 面板切换时候,触发回调 | (index: number) => void |
onAnimationEnd | 内部 swiper 组件的 onAnimationEnd 事件(仅在基础库 1.50.0 以上版本生效) | (e: any) => void=> void |
onTouchStart | 内部 swiper 组件的 onTouchStart 事件(仅在基础库 2.x 版本生效) | (e: any) => void |
onTransition | 内部 swiper 组件的 onTransition 事件(仅在基础库 2.x 版本生效) | (e: any) => void |
插槽
Tabs
名称 | 说明 |
plus | 表单项额外内容 |
作用域插槽
Tabs
名称 | 说明 |
title | 自定义 tab 标题样式。 |
样式类
Tabs
类名 | 说明 |
amd-tabs | 整体样式。 |
amd-tabs-bar | 上方标题区域样式。 |
| 上方标题区域激活时样式。 |
| 上方标题区域激活时 indicator 样式。 |
amd-tabs-bar | 上方标题区域样式。 |
amd-tabs-bar-sticky | 吸顶状态样式。 |
amd-tabs-bar-plus | 右上角标签样式。 |
amd-tabs-bar-fade | 两侧渐淡效果样式。 |
amd-tabs-bar-fade-left | 左侧渐淡效果样式。 |
amd-tabs-bar-fade-right | 右侧渐淡效果样式。 |
amd-tabs-bar-scroll-view | 内部 ScrollView 组件样式。 |
amd-tabs-bar-wrap | 每个标题的样式。 |
amd-tabs-bar-item | 每个标题的样式。 |
amd-tabs-bar-basis | type 为 basis 时,每个标题的样式。 |
amd-tabs-bar-capsule | type 为 capsule 时,每个标题的样式。 |
amd-tabs-bar-capsule-title | type 为 capsule 时,每个标题内部文字的样式。 |
amd-tabs-bar-capsule-badge | type 为 capsule 时,每个标题内部 badge 的样式。 |
amd-tabs-bar-mixin | 内type 为 mixin 时,每个标题的样式。 |
amd-tabs-bar-mixin-title | 内type 为 mixin 时,每个标题的文字样式。 |
amd-tabs-bar-mixin-subtitle | 内type 为 mixin 时,每个标题的副标题样式。 |
amd-tabs-bar-disabled | 禁用态选项卡样式。 |
TabItem
类名 | 说明 |
amd-tabs-item | 选项卡菜单的样式。 |
amd-tabs-item-pane | 选项卡下面的内容面板样式。 |
代码示例
基本使用
index.axml 的代码示例如下:
<view>
<tabs
index="{{index}}"
type="{{type}}"
animation="{{animation}}"
swipeable="{{swipeable}}"
sticky="{{sticky}}"
onChange="handleChangeTab">
<view a:if="{{plusSlot}}" slot="plus" >
<icon
size="small"
type="AddOutline"
className="plus-icon"
onTap="handleClickIcon" />
</view>
<view
a:if="{{titleSlot}}"
slot-scope="prop"
slot="title">
{{prop.tab.title + ' slot'}}
</view>
<block a:for="{{tabs}}">
<tab-content
a:if="{{index === 1}}"
tab="{{item}}">
<view>
{{item.title}}
<view
a:for="{{height}}">
........根据内容自适应高度........
</view>
</view>
</tab-content>
<tab-content
a:elif="{{index === 3}}"
tab="{{item}}">
<view style="height: 30vh">
........{{item.title}}........
<text>父级设置了高度后的变化</text>
</view>
</tab-content>
<tab-content tab="{{item}}" a:else badge="{{item.badge}}">
<view style="height: 20vh">
........{{item.title}}........
</view>
</tab-content>
</block>
</tabs>
<list radius className="actions">
<list-item>
选项数
<radio-group
slot="extra"
class="radio-group"
name="tabsNumber"
onChange="handleChangeTabNum" >
<label
class="radio"
a:for="{{tabsNumber}}">
<radio
value="{{item.name}}"
checked="{{item.checked}}" />
<text
class="radio-text">
{{item.value}}
</text>
</label>
</radio-group>
</list-item>
<list-item>
type
<radio-group
slot="extra"
class="radio-group"
name="tabsType"
onChange="handleChangeType" >
<label
class="radio"
a:for="{{tabsType}}">
<radio
value="{{item.name}}"
checked="{{item.checked}}" />
<text
class="radio-text">
{{item.value}}
</text>
</label>
</radio-group>
</list-item>
<list-item>
内容过渡动画<switch checked="{{animation}}" controlled onChange="handleChangeAnimation" slot="extra"/>
</list-item>
<list-item>
支持手势切换<switch checked="{{swipeable}}" controlled onChange="handleChangeSwipeable" slot="extra"/>
</list-item>
<list-item brief="sticky效果">
吸顶<switch checked="{{sticky}}" controlled onChange="handleChangeSticky" slot="extra"/>
</list-item>
<list-item brief="自定义tab展示,优先级高于配置">
title插槽<switch checked="{{titleSlot}}" controlled onChange="handleChangeTitleSlot" slot="extra"/>
</list-item>
<list-item brief="右上角操作按钮">
plus插槽<switch checked="{{plusSlot}}" controlled onChange="handleChangePlusSlot" slot="extra"/>
</list-item>
</list>
</view>
index.js 的代码示例如下:
Page({
data: {
index: 0,
height: 30,
type: 'basis',
animation: true,
swipeable: true,
titleSlot: false,
plusSlot: true,
sticky: false,
tabs: [
{
title: '选项一',
subTitle: '描述文案',
},
{
title: '选项二',
subTitle: '描述文案描述',
},
{
title: '选项三',
subTitle: '描述',
},
],
tabsType: [
{ name: 'basis', value: '普通', checked: true },
{ name: 'capsule', value: '胶囊' },
{ name: 'mixin', value: '带描述' },
],
tabsNumber: [
{ name: '1', value: '一条' },
{ name: '2', value: '两条' },
{ name: '3', value: '三条', checked: true },
{ name: '-1', value: '很多' },
],
},
handleChangeAnimation(checked) {
this.setData({ animation: checked });
},
handleChangeSwipeable(checked) {
this.setData({ swipeable: checked });
},
handleChangeSticky(checked) {
this.setData({ sticky: checked });
},
handleChangeTitleSlot(checked) {
this.setData({ titleSlot: checked });
},
handleChangePlusSlot(checked) {
this.setData({ plusSlot: checked });
},
handleChangeType(e) {
this.setData({
type: e.detail.value,
});
},
// tabs 的点击回调
handleChangeTab(e) {
this.setData({
index: e,
});
},
// 右上角的 plus 区域点击事件
handleClickIcon() {
my.alert({
title: 'slot="plus"',
content: '自定义 slot 的 icon 被点击',
});
},
handleChangeTabNum(e) {
if (e.detail.value === '1') {
this.setData({
tabs: [
{
title: '选项',
subTitle: '描述文案',
badge: 6,
},
],
});
} else if (e.detail.value === '2') {
this.setData({
tabs: [
{
title: '选项',
subTitle: '描述文案',
},
{
title: '选项二',
subTitle: '描述文案描述',
},
],
});
} else if (e.detail.value === '3') {
this.setData({
tabs: [
{
title: '选项一',
subTitle: '描述文案',
},
{
title: '选项二',
subTitle: '描述文案描述',
},
{
title: '选项三',
subTitle: '描述',
},
],
});
} else {
this.setData({
tabs: [
{
title: '选项一',
subTitle: '描述文案',
},
{
title: '选项二',
subTitle: '描述文案描述',
},
{
title: '选项三',
subTitle: '描述',
},
{
title: '4 Tab',
subTitle: '描述',
showBadge: true,
badge: 1,
},
{
title: '5 Tab',
subTitle: '描述',
badge: 999,
},
{
title: '3 Tab',
subTitle: '描述',
},
{
title: '4 Tab',
subTitle: '描述',
},
{
title: '151111 Tab',
subTitle: '描述',
},
{
title: '42345 Tab',
subTitle: '描述',
},
{
title: '1511116787 Tab',
subTitle: '描述',
},
{
title: '42452 Tab',
subTitle: '描述',
},
{
title: '15451111 Tab',
},
{
title: '4234 Tab',
subTitle: '描述',
},
{
title: '11251111 Tab',
subTitle: '描述',
},
{
title: '44123 Tab',
},
{
title: '1531111 Tab',
subTitle: '描述',
},
{
title: '41 Tab',
},
{
title: '15111111 Tab',
},
],
});
}
},
});
index.acss 的代码示例如下:
.actions {
margin-top: 24px;
}
.amd-tabs-item-pane view {
background-color: #fff;
padding: 24rpx;
}
.plus-icon {
font-size: 48rpx;
}
index.json 的代码示例如下:
{
"defaultTitle": "Tabs",
"usingComponents": {
"tabs": "antd-mini/es/Tabs/index",
"tab-content": "antd-mini/es/Tabs/TabItem/index",
"icon": "antd-mini/es/Icon/index",
"list": "antd-mini/es/List/index",
"list-item": "antd-mini/es/List/ListItem/index",
"switch": "antd-mini/es/Switch/index",
"demo-block": "../../components/DemoBlock/index"
}
}
fallback
index.axml 的代码示例如下:
<tabs
index="{{curIdx}}"
type="{{type}}"
fallback="{{true}}"
sticky="{{sticky}}"
onChange="changeTab">
<block a:for="{{tabs}}">
<tab-content
style="{{curIdx===index ? '' : 'display:none'}}"
tab="{{item}}">
<view>
{{item.title}}
<view
a:for="{{height}}">
........根据内容自适应高度........
</view>
</view>
</tab-content>
</block>
</tabs>
index.js 的代码示例如下:
const component2 = my.canIUse('component2');
Page({
data: {
curIdx: 2,
height: 30,
type: 'basis',
animation: false,
swipeable: false,
titleSlot: false,
plusSlot: true,
sticky: false,
tabs: [
{
title: '选项一',
subTitle: '描述文案',
corner: true,
},
{
title: '选项二',
subTitle: '描述文案描述',
},
{
title: '选项三',
subTitle: '描述',
},
],
tabsType: [
{ name: 'basis', value: '普通', checked: true },
{ name: 'capsule', value: '胶囊' },
{ name: 'mixin', value: '带描述' },
],
tabsNumber: [
{ name: '1', value: '一条' },
{ name: '2', value: '两条' },
{ name: '3', value: '三条' },
{ name: '-1', value: '很多', checked: true },
],
tabsAnimation: [
{ name: true, value: 'true' },
{ name: false, value: 'false', checked: true },
],
tabsSwipeable: [
{ name: true, value: 'true' },
{ name: false, value: 'false', checked: true },
],
tabsTitleSlotScope: [
{ name: true, value: 'true' },
{ name: false, value: 'false', checked: true },
],
tabsSticky: [
{ name: true, value: 'true' },
{ name: false, value: 'false', checked: true },
],
tabsPlusSlotScope: [
{ name: true, value: 'true', checked: true },
{ name: false, value: 'false' },
],
canSwipe: true,
},
onLoad() {
if (!component2) {
this.setData({
canSwipe: component2,
});
}
},
// tabs 的点击回调
changeTab(e) {
this.setData({
curIdx: e,
});
},
// 右上角的 plus 区域点击事件
iconClick() {
my.alert({
title: 'slot="plus"',
content: '自定义 slot 的 icon 被点击',
});
},
});
index.json 的代码示例如下:
{
"defaultTitle": "Tabs",
"usingComponents": {
"tabs": "antd-mini/es/Tabs/index",
"tab-content": "antd-mini/es/Tabs/TabItem/index",
"icon": "antd-mini/es/Icon/index"
}
}