標籤:
最近搞一個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 一次就可以了。
當然,我那個傻瓜式的方式也挺好的。哈哈,任君喜歡
如果您覺得文章有用,也可以給鹹魚老弟發個小額紅包鼓勵鼓勵,哈哈
react做tab切換的幾種方式