TabBar 标签栏
位于 APP 底部,方便用户在不同功能模块之间进行快速切换。规则
用作 APP 的一级分类,数量控制在 3-5 个之间。
即使某个 Tab 不可用,也不要禁用或者移除该 Tab。
使用 Badge 进行提示,足不出户也能知道有内容更新。
代码演示
多用于页面的内容区块,起着控制小范围内的大块内容的分组和隐藏,起着保持界面整洁的作用。
import { TabBar } from 'antd-mobile';
class TabBarExample extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'redTab',
hidden: false,
fullScreen: false,
};
}
renderContent(pageText) {
return (
<div style={{ backgroundColor: 'white', height: '100%', textAlign: 'center' }}>
<div style={{ paddingTop: 60 }}>Clicked “{pageText}” tab, show “{pageText}” information</div>
<a style={{ display: 'block', marginTop: 40, marginBottom: 20, color: '#108ee9' }}
onClick={(e) => {
e.preventDefault();
this.setState({
hidden: !this.state.hidden,
});
}}
>
Click to show/hide tab-bar
</a>
<a style={{ display: 'block', marginBottom: 600, color: '#108ee9' }}
onClick={(e) => {
e.preventDefault();
this.setState({
fullScreen: !this.state.fullScreen,
});
}}
>
Click to switch fullscreen
</a>
</div>
);
}
render() {
return (
<div style={this.state.fullScreen ? { position: 'fixed', height: '100%', width: '100%', top: 0 } : { height: 400 }}>
<TabBar
unselectedTintColor="#949494"
tintColor="#33A3F4"
barTintColor="white"
hidden={this.state.hidden}
>
<TabBar.Item
title="Life"
key="Life"
icon={<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/sifuoDUQdAFKAVcFGROC.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/iSrlOTqrKddqbOmlvUfq.svg) center center / 21px 21px no-repeat' }}
/>
}
selected={this.state.selectedTab === 'blueTab'}
badge={1}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
});
}}
data-seed="logId"
>
{this.renderContent('Life')}
</TabBar.Item>
<TabBar.Item
icon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://gw.alipayobjects.com/zos/rmsportal/BTSsmHkPsQSPTktcXyTV.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://gw.alipayobjects.com/zos/rmsportal/ekLecvKBnRazVLXbWOnE.svg) center center / 21px 21px no-repeat' }}
/>
}
title="Koubei"
key="Koubei"
badge={'new'}
selected={this.state.selectedTab === 'redTab'}
onPress={() => {
this.setState({
selectedTab: 'redTab',
});
}}
data-seed="logId1"
>
{this.renderContent('Koubei')}
</TabBar.Item>
<TabBar.Item
icon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/psUFoAMjkCcjqtUCNPxB.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/IIRLrXXrFAhXVdhMWgUI.svg) center center / 21px 21px no-repeat' }}
/>
}
title="Friend"
key="Friend"
dot
selected={this.state.selectedTab === 'greenTab'}
onPress={() => {
this.setState({
selectedTab: 'greenTab',
});
}}
>
{this.renderContent('Friend')}
</TabBar.Item>
<TabBar.Item
icon={{ uri: 'https://zos.alipayobjects.com/rmsportal/asJMfBrNqpMMlVpeInPQ.svg' }}
selectedIcon={{ uri: 'https://zos.alipayobjects.com/rmsportal/gjpzzcrPMkhfEqgbYvmN.svg' }}
title="My"
key="my"
selected={this.state.selectedTab === 'yellowTab'}
onPress={() => {
this.setState({
selectedTab: 'yellowTab',
});
}}
>
{this.renderContent('My')}
</TabBar.Item>
</TabBar>
</div>
);
}
}
ReactDOM.render(<TabBarExample />, mountNode);
#tab-bar.demo {
display: flex;
flex-direction: column;
}
#tab-bar .demoName {
height: 40px;
}
#tab-bar .demo-preview-item .am-tab-bar {
background-color: white;
}
import { TabBar, ListView } from 'antd-mobile';
const data = [
{
img: 'https://zos.alipayobjects.com/rmsportal/dKbkpPXKfvZzWCM.png',
title: 'Meet hotel',
des: '不是所有的兼职汪都需要风吹日晒',
},
{
img: 'https://zos.alipayobjects.com/rmsportal/XmwCzSeJiqpkuMB.png',
title: 'McDonald\'s invites you',
des: '不是所有的兼职汪都需要风吹日晒',
},
{
img: 'https://zos.alipayobjects.com/rmsportal/hfVtzEhPzTUewPm.png',
title: 'Eat the week',
des: '不是所有的兼职汪都需要风吹日晒',
},
];
const NUM_SECTIONS = 5;
const NUM_ROWS_PER_SECTION = 5;
let pageIndex = 0;
const dataBlobs = {};
let sectionIDs = [];
let rowIDs = [];
function genData(pIndex = 0) {
for (let i = 0; i < NUM_SECTIONS; i++) {
const ii = (pIndex * NUM_SECTIONS) + i;
const sectionName = `Section ${ii}`;
sectionIDs.push(sectionName);
dataBlobs[sectionName] = sectionName;
rowIDs[ii] = [];
for (let jj = 0; jj < NUM_ROWS_PER_SECTION; jj++) {
const rowName = `S${ii}, R${jj}`;
rowIDs[ii].push(rowName);
dataBlobs[rowName] = rowName;
}
}
sectionIDs = [...sectionIDs];
rowIDs = [...rowIDs];
}
class ListViewExample extends React.Component {
constructor(props) {
super(props);
const getSectionData = (dataBlob, sectionID) => dataBlob[sectionID];
const getRowData = (dataBlob, sectionID, rowID) => dataBlob[rowID];
const dataSource = new ListView.DataSource({
getRowData,
getSectionHeaderData: getSectionData,
rowHasChanged: (row1, row2) => row1 !== row2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
});
this.state = {
dataSource,
isLoading: true,
height: (document.documentElement.clientHeight * 3) / 4,
};
}
componentDidMount() {
const hei = document.documentElement.clientHeight - ReactDOM.findDOMNode(this.lv).parentNode.offsetTop;
setTimeout(() => {
genData();
this.setState({
dataSource: this.state.dataSource.cloneWithRowsAndSections(dataBlobs, sectionIDs, rowIDs),
isLoading: false,
height: hei,
});
}, 600);
}
onEndReached = (event) => {
if (this.state.isLoading && !this.state.hasMore) {
return;
}
console.log('reach end', event);
this.setState({ isLoading: true });
setTimeout(() => {
genData(++pageIndex);
this.setState({
dataSource: this.state.dataSource.cloneWithRowsAndSections(dataBlobs, sectionIDs, rowIDs),
isLoading: false,
});
}, 1000);
}
render() {
const separator = (sectionID, rowID) => (
<div
key={`${sectionID}-${rowID}`}
style={{
backgroundColor: '#F5F5F9',
height: 8,
borderTop: '1px solid #ECECED',
borderBottom: '1px solid #ECECED',
}}
/>
);
let index = data.length - 1;
const row = (rowData, sectionID, rowID) => {
if (index < 0) {
index = data.length - 1;
}
const obj = data[index--];
return (
<div key={rowID} style={{ padding: '0 15px' }}>
<div
style={{
lineHeight: '50px',
color: '#888',
fontSize: 18,
borderBottom: '1px solid #F6F6F6',
}}
>{obj.title}</div>
<div style={{ display: 'flex', padding: '15px 0' }}>
<img style={{ height: '64px', marginRight: '15px' }} src={obj.img} alt="" />
<div style={{ lineHeight: 1 }}>
<div style={{ marginBottom: '8px', fontWeight: 'bold' }}>{obj.des}</div>
<div><span style={{ fontSize: '30px', color: '#FF6E27' }}>35</span>¥ {rowID}</div>
</div>
</div>
</div>
);
};
return (
<ListView
ref={el => this.lv = el}
dataSource={this.state.dataSource}
renderHeader={() => <span>header</span>}
renderFooter={() => (<div style={{ padding: 30, textAlign: 'center' }}>
{this.state.isLoading ? 'Loading...' : 'Loaded'}
</div>)}
renderSectionHeader={sectionData => (
<div>{`Task ${sectionData.split(' ')[1]}`}</div>
)}
renderRow={row}
renderSeparator={separator}
style={{
height: this.state.height,
overflow: 'auto',
}}
pageSize={4}
onScroll={() => { console.log('scroll'); }}
scrollRenderAheadDistance={500}
onEndReached={this.onEndReached}
onEndReachedThreshold={10}
/>
);
}
}
class TabBarExample extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'blueTab',
hidden: false,
};
}
renderContent(pageText) {
return (
<div style={{ backgroundColor: 'white', height: '100%', textAlign: 'center' }}>
<div style={{ paddingTop: 60 }}>Clicked “{pageText}” tab, show “{pageText}” information</div>
<a style={{ display: 'block', marginTop: 40, marginBottom: 20, color: '#108ee9' }}
onClick={(e) => {
e.preventDefault();
this.setState({
hidden: !this.state.hidden,
});
}}
>
Click to show/hide tab-bar
</a>
</div>
);
}
render() {
return (
<div style={{ position: 'fixed', height: '100%', width: '100%', top: 0 }}>
<TabBar
unselectedTintColor="#949494"
tintColor="#33A3F4"
barTintColor="white"
tabBarPosition="bottom"
hidden={this.state.hidden}
prerenderingSiblingsNumber={0}
>
<TabBar.Item
title="Life"
key="Life"
icon={<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/sifuoDUQdAFKAVcFGROC.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/iSrlOTqrKddqbOmlvUfq.svg) center center / 21px 21px no-repeat' }}
/>
}
selected={this.state.selectedTab === 'blueTab'}
badge={1}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
});
}}
data-seed="logId"
>
<ListViewExample />
</TabBar.Item>
<TabBar.Item
icon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://gw.alipayobjects.com/zos/rmsportal/BTSsmHkPsQSPTktcXyTV.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://gw.alipayobjects.com/zos/rmsportal/ekLecvKBnRazVLXbWOnE.svg) center center / 21px 21px no-repeat' }}
/>
}
title="Koubei"
key="Koubei"
badge={'new'}
selected={this.state.selectedTab === 'redTab'}
onPress={() => {
this.setState({
selectedTab: 'redTab',
});
}}
data-seed="logId1"
>
{this.renderContent('Koubei')}
</TabBar.Item>
<TabBar.Item
icon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/psUFoAMjkCcjqtUCNPxB.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/IIRLrXXrFAhXVdhMWgUI.svg) center center / 21px 21px no-repeat' }}
/>
}
title="Friend"
key="Friend"
dot
selected={this.state.selectedTab === 'greenTab'}
onPress={() => {
this.setState({
selectedTab: 'greenTab',
});
}}
>
{this.renderContent('Friend')}
</TabBar.Item>
<TabBar.Item
icon={{ uri: 'https://zos.alipayobjects.com/rmsportal/asJMfBrNqpMMlVpeInPQ.svg' }}
selectedIcon={{ uri: 'https://zos.alipayobjects.com/rmsportal/gjpzzcrPMkhfEqgbYvmN.svg' }}
title="My"
key="my"
selected={this.state.selectedTab === 'yellowTab'}
onPress={() => {
this.setState({
selectedTab: 'yellowTab',
});
}}
>
{this.renderContent('My')}
</TabBar.Item>
</TabBar>
</div>
);
}
}
ReactDOM.render(<TabBarExample />, mountNode);
控制 Tabbar 显示在顶部
.am-tab-bar::-webkit-scrollbar {
display: none;
}
#tab-bar.demo {
display: flex;
flex-direction: column;
}
#tab-bar .demoName {
height: 40px;
}
#tab-bar .demo-preview-item .am-tab-bar {
background-color: white;
}
import { TabBar } from 'antd-mobile';
class TabBarExample extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'redTab',
hidden: false,
fullScreen: false,
};
}
renderContent(pageText) {
return (
<div style={{ backgroundColor: 'white', height: '100%', textAlign: 'center' }}>
<div style={{ paddingTop: 60 }}>Clicked “{pageText}” tab, show “{pageText}” information</div>
<a style={{ display: 'block', marginTop: 40, marginBottom: 20, color: '#108ee9' }}
onClick={(e) => {
e.preventDefault();
this.setState({
hidden: !this.state.hidden,
});
}}
>
Click to show/hide tab-bar
</a>
<a style={{ display: 'block', marginBottom: 600, color: '#108ee9' }}
onClick={(e) => {
e.preventDefault();
this.setState({
fullScreen: !this.state.fullScreen,
});
}}
>
Click to switch fullscreen
</a>
</div>
);
}
render() {
return (
<div style={this.state.fullScreen ? { position: 'fixed', height: '100%', width: '100%', top: 0 } : { height: 400 }}>
<TabBar
unselectedTintColor="#949494"
tintColor="#33A3F4"
barTintColor="white"
hidden={this.state.hidden}
tabBarPosition="top"
>
<TabBar.Item
title="Life"
key="Life"
icon={<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/sifuoDUQdAFKAVcFGROC.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/iSrlOTqrKddqbOmlvUfq.svg) center center / 21px 21px no-repeat' }}
/>
}
selected={this.state.selectedTab === 'blueTab'}
badge={1}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
});
}}
data-seed="logId"
>
{this.renderContent('Life')}
</TabBar.Item>
<TabBar.Item
icon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://gw.alipayobjects.com/zos/rmsportal/BTSsmHkPsQSPTktcXyTV.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://gw.alipayobjects.com/zos/rmsportal/ekLecvKBnRazVLXbWOnE.svg) center center / 21px 21px no-repeat' }}
/>
}
title="Koubei"
key="Koubei"
badge={'new'}
selected={this.state.selectedTab === 'redTab'}
onPress={() => {
this.setState({
selectedTab: 'redTab',
});
}}
data-seed="logId1"
>
{this.renderContent('Koubei')}
</TabBar.Item>
<TabBar.Item
icon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/psUFoAMjkCcjqtUCNPxB.svg) center center / 21px 21px no-repeat' }}
/>
}
selectedIcon={
<div style={{
width: '22px',
height: '22px',
background: 'url(https://zos.alipayobjects.com/rmsportal/IIRLrXXrFAhXVdhMWgUI.svg) center center / 21px 21px no-repeat' }}
/>
}
title="Friend"
key="Friend"
dot
selected={this.state.selectedTab === 'greenTab'}
onPress={() => {
this.setState({
selectedTab: 'greenTab',
});
}}
>
{this.renderContent('Friend')}
</TabBar.Item>
<TabBar.Item
icon={{ uri: 'https://zos.alipayobjects.com/rmsportal/asJMfBrNqpMMlVpeInPQ.svg' }}
selectedIcon={{ uri: 'https://zos.alipayobjects.com/rmsportal/gjpzzcrPMkhfEqgbYvmN.svg' }}
title="My"
key="my"
selected={this.state.selectedTab === 'yellowTab'}
onPress={() => {
this.setState({
selectedTab: 'yellowTab',
});
}}
>
{this.renderContent('My')}
</TabBar.Item>
</TabBar>
</div>
);
}
}
ReactDOM.render(<TabBarExample />, mountNode);
#tab-bar.demo {
display: flex;
flex-direction: column;
}
#tab-bar .demoName {
height: 40px;
}
#tab-bar .demo-preview-item .am-tab-bar {
background-color: white;
}
API
TabBar
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
barTintColor | tabbar 背景色 | String | white |
tintColor | 选中的字体颜色 | String | #108ee9 |
unselectedTintColor | 未选中的字体颜色 | String | '#888' |
hidden | 是否隐藏 | Boolean | false |
prefixCls | 样式前缀 | String | 'am-tab-bar' |
noRenderContent | 不渲染内容部分 | Boolean | false |
prerenderingSiblingsNumber | 预加载相邻的tab内容, Infinity: 加载所有的tab内容, 0: 仅加载当前tab内容, 当页面较复杂时,建议设为0,提升页面加载性能 | number | 1 |
tabBarPosition | tabbar 位置 | 'top'|'bottom' | 'bottom' |
TabBar.Item
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
badge | 徽标数 | Number \ String | 无 |
dot | 是否在右上角显示小红点(在设置badge的情况下失效) | Boolean | false |
onPress | bar 点击触发,需要自己改变组件 state & selecte={true} | Function | (){} |
selected | 是否选中 | Boolean | false |
icon | 默认展示图片 | 见 demo | |
selectedIcon | 选中后的展示图片 | 见 demo | |
title | 标题文字 | String | |
key | 唯一标识 | String | 无 |