頂部導(dǎo)航組件
IMG_3827.PNG
調(diào)用示例:
<TabBar activeKey={this.state.activeKey}
onChange={this.tabChange.bind(this)}> //點擊事件里要更改stata.activeKey來觸發(fā)組件更新
<TabBar.Item title={`頁面1`} tabKey={'page1'}>
//tab頁1
</TabBar.Item>
<TabBar.Item title={`頁面2`} tabKey={'page2'}>
//tab頁2
</TabBar.Item>
</TabBar>
選擇事件:
tabChange({next: tabKey}){
this.setState({activeKey: tabKey});
}
具體實現(xiàn)
export default class TabBar extends PureComponent {
static Item = Item //子組件
constructor(props) {
super(props);
//存儲tab頁id以及坐標,用于實現(xiàn)動畫觸發(fā)
const map = new Map();
props.children.forEach((child, index) => {
//默認頁面寬度為750,tabbar長度為80
const length = 750 / props.children.length;
const position = index * length + length / 2 - 42
map.set(child.props.tabKey, position);
})
this.state = {
map
}
}
componentDidMount() {
const left_new = this.state.map.get(this.props.activeKey)
const dom = this.refs.border
//初始動畫渲染
doTransition(dom, {transform: `translateX(${left_new + 80})`})
}
changeSelect(key) {//選擇事件
//獲取點擊tab頁的坐標
const left_new = this.state.map.get(key)
const dom = this.refs.border
//平移底部border
doTransition(dom, {transform: `translateX(${left_new + 80})`}, null, () => {
//回調(diào)
this.props.onChange && this.props.onChange({next: key})
})
}
getChild() {//獲取子tab頁
//根據(jù)tab頁id獲取頁面內(nèi)容
let child = this.props.children.find(child => {
return child.props.tabKey == this.props.activeKey
})
}
頁面內(nèi)容渲染
render(){
let child = this.getChild()
return (
<View style={[style.container,
this.props.full ? {flex: 1} : '',
this.props.style ? this.props.style : '']}>
<View style={style.borderContainer}>
<View style={style.body}>
//渲染導(dǎo)航
{this.props.children.map(obj => {
const flag = obj.props.tabKey == this.props.activeKey
return (
<TouchableHighlight
onPress={this.changeSelect.bind(this, obj.props.tabKey)}
style={style.tab}>
<View style={{flex: 1}}/>//平分頁面占比
<View style={{flexDirection: "row"}}>
<Text style={flag ?
style.tabTextFocus
:
style.tabText}>{obj.props.title}
</Text>
{obj.props.nextTitle ?
<Text style={obj.props.nextTitle === "(有)" ?
style.yesText
:
style.noText}>{obj.props.nextTitle}</Text>
: null}
</View>
<View style={style.num}>
<Text style={flag ?
style.numFocus : style.numText}>
{!obj.props.total ||
(obj.props.total == 0 && !this.props.showZero) ?
'' :
obj.props.total > 9999 ?
`(9999+)` : `(${obj.props.total})`}
</Text>
</View>
</TouchableHighlight>)
})}
</View>
//底部border
<View style={style.bottom}>
<View ref={`border`} style={[style.bottom_border]}/>
</View>
</View>
//渲染根據(jù)tabkey得到的子組件
{child}
</View>)
}
子組件實現(xiàn):
import {createElement, PureComponent, render} from 'rax';
import {View, Text} from 'nuke';
import style from "./style.less"
export default class TabBarItem extends PureComponent{
constructor(props){
super(props);
}
render(){
return(
<View style={style.children}>
{this.props.children}
</View>
)
}
}