【原】react做tab切換的幾種方式


最近搞一個pc端的活動,搞了一個多月,甚煩,因為相比於pc端,更喜歡移動端多一點。因為移動端又能搞我的react了.

  今天主要總結一下react當中tab切換的幾種方式,因為tab切換基本上都會用到。當然,你也可以在react當中用jquery或者zepto來實現,不過既然都用react了,能不能用jq,就盡量不用jq。不過不得不吐槽一下,在jquery很簡單的東西,在react中稍微復雜化了一點。

 

目前我用到的tab切換只有兩種方式,所以暫時總結這兩種,以后有遇到其他的再總結。

 

第一種、只是子標簽在換,內容的布局不換。類似於下面這種

這類的切換只需要點擊上面的標簽,發送不同的請求而已,下面內容的布局都是一樣的。

 

第二種就是標簽頁和內容都需要切換的,也是比較常見的這種。如下

 

Talk is cheap. Show me the code     (覺得比較有意思的翻譯是:廢話少說,放碼過來)

 

第一種,只是tab標簽切換的方式

 

import React from 'react';

class NewsList extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            tabs:[
                {tabName:"熱點新聞",id:1},
                {tabName:"合作播報",id:2},
                {tabName:"行業咨詢",id:3},
                {tabName:"運營攻略",id:4}
            ],
            currentIndex:1,
        };
    }    
    componentDidMount() {
        
    }
    tabChoiced=(id)=>{
        // tab切換的方法
        this.setState({
            currentIndex:id
        });
    }
    render(){
        var _this=this;
          var tabList= this.state.tabs.map(function(res,index) {
              // 遍歷標簽頁,如果標簽的id等於tabid,那么該標簽就加多一個active的className
            var tabStyle=res.id==this.state.currentIndex ? 'subCtrl active' : 'subCtrl';

            return    <li key={index} onClick={this.tabChoiced.bind(_this,res.id)} className={tabStyle}>{res.tabName}</li>

        }.bind(_this));
        return (
            <div className="listWrap">
                <ul className="subNavWrap">
                    {tabList}
                </ul>
                <div className="newsList">
                    {/**這里通用的新聞列表**/}
                </div>
            </div>
        )
    }
}

export default NewsList;

 

    首先我們初始化已給tab標簽的數組,並給數組里面的每一項加個id,然后設置一個當前顯示第幾個的currendIndex.然后將標簽遍歷出來,如果該標簽的id等於currendIndex,那么就加多一個active的className,否則沒有。從而實現點擊標簽,顯示高亮的狀態

  每次點擊新的標簽,都會將該標簽對應的id傳過去,從而讓currendIndex等於被點擊的標簽的id。比如點擊了id為2的標簽,這樣下次遍歷的時候currendIndex也等於2了,從而讓第二個處於高亮,從而實現tab的切換。

 

第二種,內容隨着標簽一起切換

 

這個也是比較常見的。暫時我這里有兩種方法實現。

 

方法1:在前面只是標簽切換形式上改進一下:

 

import React from 'react';

class NewsList extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            tabs:[
                {tabName:"社會新聞",id:1},
                {tabName:"體育世界",id:2},
                {tabName:"娛樂圈",id:3},
            ],
            currentIndex:1,
        };
    }    
    componentDidMount() {
        
    }
    tabChoiced=(id)=>{
        //tab切換到方法
        this.setState({
            currentIndex:id
        });
    }
    render(){
        var _this=this;
        var isBox1Show=this.state.currentIndex==1 ? 'block' : 'none';
        var isbox2Show=this.state.currentIndex==2 ? 'block' : 'none';
        var isbox3Show=this.state.currentIndex==3 ? 'block' : 'none';

          var tabList= this.state.tabs.map(function(res,index) {
              // 遍歷標簽頁,如果標簽的id等於tabid,那么該標簽就加多一個active的className
            var tabStyle=res.id==this.state.currentIndex ? 'subCtrl active' : 'subCtrl';

            return    <li key={index} onClick={this.tabChoiced.bind(_this,res.id)} className={tabStyle}>{res.tabName}</li>

        }.bind(_this));
        return (
            <div className="listWrap">
                <ul className="subNavWrap">
                    {tabList}
                </ul>
                <div className="newsList">
                    <div style={{"display":isBox1Show}} >
                        社會新聞
                    </div>
                    <div style={{"display":isBox2Show}}>
                        體育世界
                    </div>
                    <div style={{"display":isBox3Show}}>
                        娛樂圈
                    </div>
                </div>
            </div>
        )
    }
}

export default NewsList;

 

 雖然這種方法比較傻瓜式,不過很方便。在第一個代碼的的基礎上稍加改進。判斷當前的currenIndex等於幾,如果是1,那么內容頁的第一個的display就設為block, 其他內容頁的display為noe。以此類推。哈哈,確實有點點傻瓜式。管它呢,好用就好。

 

方法2:做成一個組件的形式,也可以說是寫一個小小的插件

還是廢話少說,放碼過來

var React=require("react");
var ReactDOM=require("react-dom");

class TabsControl extends React.Component{

    constructor(){
        super();
        this.state={ 
            currentIndex : 0
        };
    }

    check_tittle_index(index){
        return index===this.state.currentIndex ? "Tab_tittle active" : "Tab_tittle";
    }

    check_item_index(index){
        return index===this.state.currentIndex ? "Tab_item show" : "Tab_item";
    }

    render(){
        let _this=this;
        return(
            <div>
                {/*動態生成Tab導航*/}
                <div className="Tab_tittle_wrap">
                    { React.Children.map( this.props.children , (element,index) => {
                        return(
                            /*箭頭函數沒有自己的this,這里的this繼承自外圍作用域,即組件本身*/
                            <div onClick={ () => { this.setState({currentIndex : index}) } } className={ this.check_tittle_index(index) }>{ element.props.name }</div>
                            );
                    }) }
                </div>
                {/*Tab內容區域*/}
                <div className="Tab_item_wrap">
                    {React.Children.map(this.props.children,(element,index)=>{
                        return(
                            <div className={ this.check_item_index(index) }>{ element }</div>
                            );
                    })}
                </div>
            </div>
            );
    }
}

class TabComponent extends React.Component{

    render(){
        return(
            <div className="container">
                <TabsControl>
                    <div name="社會新聞">
                        社會新聞的內容
                    </div>
                    <div name="體育世界">
                        體育世界的內容
                    </div>
                    <div name="娛樂圈">
                        娛樂圈的內容
                    </div>
                </TabsControl>
            </div>
            );
    }
}

ReactDOM.render(<TabComponent/>,document.getElementById("app"));

    這個稍微復雜一點,稍加解釋,不過如果你看懂了前面兩個的例子,很很好懂。

 首先我們定義了一個子組件叫TabsControl ,然后我們遍歷它的子標簽。子標簽的內容從哪里來呢,是在該組件里面的name值那里獲取。

  this.props.children 是React內建的一個屬性,用來獲取組件的子元素。因為子元素有可能是Object或者Array,

所以React提供了一些處理children的輔助方法用來遍歷:React.Children.map。

  比如上面這段代碼中,this.props.children獲取了里面三個divd數組,但是假如你只要一個div呢,那么獲取的就是對象。所以需要

React.Children.map()來配合進行遍歷。

  通過上面的這段代碼,我們就很方便的進行遍歷了。比如一個頁面需要有多個tab切換,那么我們只需要引入這個TabsControl 一次就可以了。

當然,我那個傻瓜式的方式也挺好的。哈哈,任君喜歡

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM