Tabbar Tab切换

何时使用#

轻量级切换视图

API#

Tabbar#

属性 说明 类型 默认值
itemStyle 自定义tabbar-item容器的样式,会覆盖默认样式 object false
style 自定义tabbar容器的样式,会覆盖默认样式 object false
navTop 是否顶部导航,默认为底部的tabbar,可调节到顶部 boolean false
navStyle 自定义tab标题栏的样式需要传入{active: {style...}, inactive: {style...}} active对应选中样式, inactive反之 object false
navScrollable 导航是否可滚动,如果可滚动,则不限制tab宽度,横向滚动。如果不可滚动,则每个子元素flex =1 均分父容器宽度 boolean false
capsule 是否为胶囊型【此接口预留,样式暂未实现】 boolean false
iconBar 是否带icon boolean false
activeKey (必须)用于初次打开及切换到指定的tab,接收tab的key string false
onchange(embed模式无效) 切换tab时抛出prevTab和nextTab,手动更改props时不触发 funtion false
customChange(embed模式无效) 定义内置切换tab的注入方法名称,默认为changeTo,使用方法,在tabContent中直接调用this.changeTo('tab 的key') string false
customFocus(embed模式无效) 定义获得交点的hook,该方法存在tabbar在切换时会执行此方法,默认为onFoucs,在tabContent中直接定义changeTo即可,切换tab时切出为false,切入为true string false
embed 是否启用embed模式,启用后h5实现基于iframe,native环境基于embed boolean false

Tabbar.Item#

属性 说明 类型 默认值
render 自定义渲染函数,item会传入当前是否属于活动状态为参数,活动为true function
tabKey (必须)定义该tabbar的key string
preventDefaultEvent(新增) 定义是否要禁止掉默认事件 boolean
badge 透出的消息数,以小角标方式显示在右上角 string
num 透出的数字,跟在tab的title后面,展示方式 title(num) string
onPress 点击后事件handler function
title 透出的文案 string
icon 如果tabbar 设置iconbar=true,则此处设置有效,{src: 'xxx',selected:'xxx',size:'medium/large',style:{}} obj
src(仅embed模式下有效) 定义要加载的jsbundle,例如src="qap://xxx.js" string

代码演示


/** @jsx createElement */
import {createElement, Component} from 'weex-rx';
import { View, Text,Image,TouchableHighlight} from 'nuke-components';
import { Tabbar } from 'nuke';
import {mount} from 'nuke-mounter';
import {Button,Input,Icon,ListView,Modal,Iconfont} from 'nuke';

let listData = [];
for (var i = 0; i < 300; i++) {
    listData.push({key: i,pic:'//img.alicdn.com/bao/uploaded/i1/TB1gdT4KVXXXXcpXFXXwu0bFXXX.png',text:'近三个月订单' + i});
}

let listData1 = [];
for (var i = 0; i < 300; i++) {
    listData1.push({key: i,pic:'//img.alicdn.com/bao/uploaded/i1/TB1gdT4KVXXXXcpXFXXwu0bFXXX.png',text:'已完成订单' + i});
}

const styles = {
    icon1:{fontFamily: 'iconfont1', fontSize: '36rem', color:'blue', alignItems:'center'},
    tabContent: {flex: 1, alignItems: 'center'}, 
    tabText: {color: 'white', margin: 50, },
    container: {flex: 1 },
    text: {color: 'white', margin: 50 },
    customRender: {fontSize: '10rem', color: 'blue'},
    view: {flex: 1 }, 
    top: {height: 60, paddingLeft: 10, paddingRight: 10,marginBottom: 20, flexDirection: 'row'}
}

const app = {
    activeBorder: {borderTopWidth: "5rem", borderTopStyle: "solid", borderTopColor: "#337838"},
    inactiveBorder: {borderTopWidth: "5rem", borderTopStyle: "solid", borderTopColor: "#eeeeee"},
    listHeader:{height:'300rem', display:'flex', alignItems: 'center', flexDirection: 'column', justifyContent: 'center', },
    listHeaderText:{fontSize: '60rem', color:'#333333', }, 
    listHeaderSub:{fontSize: '30rem', color:'#888888', },
    listContainer:{flex: 1, backgroundColor:'#f8f8f8', }, 
    footer:{paddingTop: '50rem', paddingBottom: '50rem', backgroundColor: '#efefef', textAlign: 'center', }, 
    link:{fontSize: '32rem', }, 
    titleLink:{backgroundColor: '#ff4200', display: 'block', padding: '10rem', }, 
    img:{width: '100rem', height: '100rem', backgroundColor: '#ff4200', }, 
    cellItemIndex:{backgroundColor:'#ffffff', height: '130rem', display:'flex', paddingLeft:'20px', alignItems: 'center', flexDirection:'row', }, 
    cellItemList:{backgroundColor:'#ffffff', height:'110rem', borderBottom:'1px solid #e8e8e8', display:'flex', alignItems:' center', flexDirection:'row', }, 
    itemTextList:{flex:13, fontSize:'30rem', color:'#333333', }, 
    itemIcon:{width:'60rem', height:'60rem', flex: 2, justifyContent:'center', }, 
    cellTextView:{flex:13, display:'flex', }, 
    itemMainTitle:{fontSize:'34rem', color:'#333333', marginBottom:'10px', }, 
    itemSubTitle:{fontSize:'24rem', color:'#333333', }, 
    itemArrow:{flex: 1, width:'18px', height:'18px', }
}

class Gray extends Component {
    press() {
        this.changeTo('m3')
    }

    onFocus(status) {
      console.log('gray:', status)
    }

    render() {
        return (
            <View style={[styles.tabContent, {backgroundColor: '#888888'}]}>
                <Text style={styles.text}>Blue Tab 大家好我是nv色的区域</Text>
                <Button onPress={this.press.bind(this)} type="normal">切换为m3</Button>
            </View>
        )
    }
}

class Sub extends Component {
    press() {
        this.props.change('m3');
    }

    render() {
        return (
            <View style={[{backgroundColor: '#eeeeee', height: '200rem'}]}>
                <Text>子容器</Text>
                <Button onPress={this.press.bind(this)} type="normal">切换为m3</Button>
            </View>
        )
    }
}

class Green extends Component {

    constructor(props) {
        super(props);
        console.log('green constructor');
    }

    press(param) {
        this.changeTo(param)
    }

    getFocus(status) {
      console.log('green:', status, this)
    }
    shouldComponentUpdate(nextProps, nextState) {
        if(this.hasInit){
            console.log('green: shouldComponentUpdate', this)
            return true
        }else{
            return false
        }
    }

    render() {
        return (
            <View style={[styles.tabContent, {backgroundColor: '#337838'}]}>
                <Sub change={this.press.bind(this)}></Sub>
                <Text style={styles.text}>Blue Tab 大家好我是nv色的区域</Text>
                <Button onPress={this.press.bind(this, 'm4')} type="normal">切换为m4</Button>
            </View>
        )
    }
}

let App = class NukeDemoIndex extends Component {
    constructor() {
        super();
        this.state =  {
            notifCount: 3,
            presses: 0,
            data: listData,
            data1: listData1,
            stop: false,
            activeKey: "m2",
            test: 1
        };
        Iconfont({name:"iconfont1",url:"http://at.alicdn.com/t/font_1474198576_7440977.ttf"});
        this.index = 0;
    }

    changeTab(tab) {
        this.setState({activeKey:  tab})
    }

    _renderContent(color, pageText, num) {
        return (
          <View style={[styles.tabContent, {backgroundColor: color}]}>
            <Text style={styles.tabText}>{pageText}</Text>
            <Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
          </View>
        );
    }

    handleLoadMore() {
        var self = this;
        // 这里进行异步操作
        setTimeout(function() {
          self.index++;
          if (self.index == 5) {
            self.state.stop = true; // 加载5次后会停止加载,并去掉菊花
          }
          self.state.data.push({key: 'x',pic:'//img.alicdn.com/bao/uploaded/i1/TB1O9eAKVXXXXaPaXXXwu0bFXXX.png',text:'xx订单'}, {key: 'loadmore 2',pic:'//img.alicdn.com/bao/uploaded/i1/TB1O9eAKVXXXXaPaXXXwu0bFXXX.png',text:'xx订单'}, {key: 'loadmore 2',pic:'//img.alicdn.com/bao/uploaded/i1/TB1O9eAKVXXXXaPaXXXwu0bFXXX.png',text:'xx订单'},{key: 'loadmore 2',pic:'//img.alicdn.com/bao/uploaded/i1/TB1O9eAKVXXXXaPaXXXwu0bFXXX.png',text:'xx订单'}, {key: 'loadmore 2',pic:'//img.alicdn.com/bao/uploaded/i1/TB1O9eAKVXXXXaPaXXXwu0bFXXX.png',text:'xx订单'});
          self.setState(self.state);
        }, 1000);
    }
    linkTo(item,e) {
        console.log(e);
    }
    renderItem (item, index){
        return <TouchableHighlight style={app.cellItemList} onPress={this.linkTo.bind(this,item)}>
                <Icon src={item.pic} style={app.itemIcon} />
                <Text style={app.itemTextList}>{item.text}</Text>
                <Icon style={app.itemArrow} src="//img.alicdn.com/tfs/TB1EU2rMVXXXXcpXXXXXXXXXXXX-64-64.png" />
            </TouchableHighlight>;

    }
    renderHeader(){
        return <View style={app.listHeader}><Text style={app.showTitleText}>list</Text></View>
    }
    renderFooter(){
        return <View style={app.loading}><Text style={app.loadingText}>加载中...</Text></View>
    }
    onChange(status) {
        console.log(status)
    }

    render1(status, key) {
        return status ? <View><Text style={styles.icon1}>{"\ue608"}</Text><Text>focus</Text></View> : 
            <View><Text style={styles.icon1}>{"\ue608"}</Text><Text>blur</Text></View>
    }

    other() {
        this.setState({test: 999})
    }

    render() {
      let self = this;
          const renderTpl = <Button type="normal">m2</Button>
        return (
            <View style={styles.container}>
                <View style={{flexDirection: 'row'}, styles.top}>
                    <Text>Tabbar外部</Text>
                    <Button onPress={this.changeTab.bind(this, 'm2')} type="primary">m2</Button>
                    <Button onPress={this.changeTab.bind(this, 'm3')} type="normal">m3</Button>
                    <Button onPress={this.other.bind(this)} type="normal">other</Button>
                </View>
                <View style={styles.view}>
                <Tabbar asContainer={false} iconBar={true} navTop={false} navStyle={{active: app.activeBorder, inactive: app.inactiveBorder}} activeKey={this.state.activeKey} onChange={this.onChange.bind(this)} customChange="changeTo" customFocus="getFocus">
                  <Tabbar.Item
                        render={this.render1.bind(this)}
                        title="m1"
                        tabKey="m1"
                        icon={{src: '//img.alicdn.com/tfs/TB1cCLYMVXXXXXHXpXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1MzYIMVXXXXXYXVXXXXXXXXXX-64-64.png'}}
                      >
                      <Green></Green>
                    </Tabbar.Item>
                    <Tabbar.Item
                    render={this.render1.bind(this)}
                        title="m2"
                        tabKey="m2"
                        icon={{src: '//img.alicdn.com/tfs/TB1cCLYMVXXXXXHXpXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1MzYIMVXXXXXYXVXXXXXXXXXX-64-64.png'}}
                      >
                      <Gray changeTab={this.changeTab.bind(this)}></Gray>
                    </Tabbar.Item>
                    <Tabbar.Item
                      title="m3"
                      tabKey="m3"
                      preventDefaultEvent={true}
                      icon={{src: '//img.alicdn.com/tfs/TB1aoTvMVXXXXaKaXXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1AZ_yMVXXXXX8aXXXXXXXXXXX-64-64.png'}}
                      badge={this.state.notifCount > 0 ? this.state.notifCount : undefined}
                      onPress={() => {
                        this.setState({
                          notifCount: this.state.notifCount + 1
                        });
                      }}>
                      {this._renderContent('#783E33', 'Red Tab 大家好我是红色的区域' + this.state.notifCount, this.state.notifCount)}
                    </Tabbar.Item>
                    <Tabbar.Item
                      renderAsOriginal
                      title="m4"
                      tabKey="m4"
                      >
                      <ListView 
                        renderHeader={this.renderHeader.bind(self)}
                        renderFooter={this.renderFooter.bind(self)}
                        renderRow={self.renderItem.bind(self)} 
                        dataSource={self.state.data}
                        style={app.listContainer}
                        onEndReached={self.handleLoadMore.bind(self)} 
                      />
                    </Tabbar.Item>
                     <Tabbar.Item
                      renderAsOriginal
                      title="m5"
                      tabKey="m5"
                      icon={{src: '//img.alicdn.com/tfs/TB1.rPuMVXXXXc1aXXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1qW2uMVXXXXcUaXXXXXXXXXXX-64-64.png'}}
                      >
                      <ListView 
                        renderHeader={this.renderHeader.bind(self)}
                        renderFooter={this.renderFooter.bind(self)}
                        renderRow={self.renderItem.bind(self)} 
                        dataSource={self.state.data1}
                        style={app.listContainer}
                        onEndReached={self.handleLoadMore.bind(self)} 
                      />
                    </Tabbar.Item>
                </Tabbar>
             </View>
            </View>
        );
    }
}


mount(<App/>, mountNode);

/** @jsx createElement */
import {createElement, Component} from 'weex-rx';
import { View, Text} from 'nuke-components';
import { Tabbar } from 'nuke';
// const isWeex = typeof callNative !== 'undefined';
// import {style} from './style.scss';
// import index from './index.scss';
import {mount} from 'nuke-mounter';




let App = class NukeDemoIndex extends Component {
    constructor() {
        super();
        this.state =  {
            selectedTab: 'redTab',
            notifCount: 3,
            presses: 0,
            key: {key: 't2'}
        };

    }

    _renderContent(color, pageText, num) {
        return (
          <View style={[styles.tabContent, {backgroundColor: color}]}>
            <Text style={styles.tabText}>{pageText}</Text>
            <Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
          </View>
        );
    }
    render() {
        return (
            <Tabbar iconBar={true} activeKey={this.state.key} embed={true}>
                <Tabbar.Item
                    title="Blue Tab"
                    tabKey="t1"
                    icon={{src: '//img.alicdn.com/tfs/TB1cCLYMVXXXXXHXpXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1MzYIMVXXXXXYXVXXXXXXXXXX-64-64.png'}}
                    src="qap://button-basic.js"
                  >
                  {this._renderContent('#414A8C', 'Blue Tab 大家好我是蓝色的区域')}
                </Tabbar.Item>
                <Tabbar.Item
                  title="Red Tab"
                    tabKey="t2"
                  icon={{src: '//img.alicdn.com/tfs/TB1aoTvMVXXXXaKaXXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1AZ_yMVXXXXX8aXXXXXXXXXXX-64-64.png'}}
                  badge={this.state.notifCount > 0 ? this.state.notifCount : undefined}
                  src="qap://button-iconbutton.js"
                  >
                  {this._renderContent('#783E33', 'Red Tab 大家好我是红色的区域', this.state.notifCount)}
                </Tabbar.Item>
                <Tabbar.Item
                  tabKey="t3"
                  title="More"
                  icon={{src: '//img.alicdn.com/tfs/TB1UsjYMVXXXXXaXpXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB12mLPMVXXXXa5XFXXXXXXXXXX-64-64.png'}}
                  src="qap://button-size.js"
                  >
                  {this._renderContent('#21551C', 'Green Tab 大家好我是绿色的', this.state.presses)}
                </Tabbar.Item>
                 <Tabbar.Item
                    tabKey="t4"
                  title="More"
                  icon={{src: '//img.alicdn.com/tfs/TB1.rPuMVXXXXc1aXXXXXXXXXXX-64-64.png',selected:'//img.alicdn.com/tfs/TB1qW2uMVXXXXcUaXXXXXXXXXXX-64-64.png'}}
                  src="qap://button-size.js"
                  >
                  {this._renderContent('#21551C', 'Green Tab 大家好我是绿色的', this.state.presses)}
                </Tabbar.Item>
            </Tabbar>
        );
    }
}
let styles = {
  tabContent: {
    flex: 1,
    alignItems: 'center',
  },
  tabText: {
    color: 'white',
    margin: 50,
  },
};

mount(<App/>, mountNode);
mobile phone header