React的组件的确很方便,十分简短地实现了分页。百度一下到的React分页十分长,所以我自己写了个,虽然不是真正意义上的三行,不过也差不多了。
这是我百度到的分页代码实现:http://blog.csdn.net/xiaozhuxmen/article/details/51461269
http://www.cnblogs.com/vichily/p/6432558.html
http://www.tuicool.com/articles/FB36VjN
http://blog.csdn.net/starfd/article/details/50505499
总得来说,他们的代码都是蛮长的,但是实现思路都不太一样。下面这个是我自己写的。
加上点击事件和非分页部分的列表事件差不多100行搞定吧。
首先上分页效果图:
样式是semantic做的。用是否有active类来区分当前页和非当前页
首先是分页组件Class_Foot
var Class_Foot = React.createClass({
getInitialState: function() {
return {thispage: 1,lastpage:1,active:'active item',unactive:'item',allPage:Page_Class};
},
skipPage: function(event){
var page_num=parseInt(event.target.text);
var last_pagenum=this.state.thispage;
this.setState({
lastpage:last_pagenum,
thispage:page_num,
});
PubSub.publish('Change_Page', page_num);
},
ToFirst:function(event){
var page_num=1;
var last_pagenum=this.state.thispage;
this.setState({
lastpage:last_pagenum,
thispage:page_num,
});
PubSub.publish('Change_Page', page_num);
},
ToLast:function(event){
var page_num=Page_Class;
var last_pagenum=this.state.thispage;
this.setState({
lastpage:last_pagenum,
thispage:page_num,
});
PubSub.publish('Change_Page', page_num);
},
render: function() {
var rows = [];
if(Page_Class>7)
{
var ac=this.state.active;var unac=this.state.unactive;var tp=this.state.thispage;var pc=Page_Class;var bool1=(tp<4),bool2=(tp<=(pc-3));var _tmp1=bool1?1:(bool2?-3:pc-6),_tmp2=bool1?7:(bool2?3:pc);
for(var j=_tmp1;j<=_tmp2;j++)
{
rows.push(<a key={"1_"+j} onClick={this.skipPage} className={bool1?((j==tp)?ac:unac):(bool2?((j==0)?ac:unac):((tp==j)?ac:unac))}>{bool1?j:(bool2?(tp+j):j)}</a>)
}
}else{
for(var j=1;j<=Page_Class;j++)
{
rows.push(<a key={"2_"+j} onClick={this.skipPage} className={(j==this.state.thispage)?this.state.active:this.state.unactive}>{j}</a>);
}
}
return <tfoot><tr><th colSpan='6'><div className="ui right floated pagination menu"><a onClick={this.ToFirst} data-tooltip='前往首页' data-position='bottom center' className="icon item"><i className="arrow left icon"></i></a>{rows}<a onClick={this.ToLast} data-tooltip='末页' className="icon item"><i className="arrow right icon"></i></a></div></th></tr></tfoot>;
}
});
声明了5个属性,thispage当前页,lastpage历史页,active当前页样式
unactive普通样式,allpage总页数
其实总页数这样的属性应该作为props
skippage和tofirst和tolast三个是onClick函数,分别对应点击页码、左侧箭头、右侧箭头.点击后的页面刷新是通过setState方法来更改state使组件立刻刷新实现的,PubSub用于发布更新状态使页面组件接收消息也刷新。
为什么我说分页只有三行代码呢?因为最关键的控制分页按钮显示的只有一个for循环,当然考虑到页数小于7页的情况就要加上一个for循环了。
核心代码:
for(var j=_tmp1;j<=_tmp2;j++)
{
rows.push(<a key={"1_"+j} onClick={this.skipPage} className={bool1?((j==tp)?ac:unac):(bool2?((j==0)?ac:unac):((tp==j)?ac:unac))}>{bool1?j:(bool2?(tp+j):j)}</a>)
}
用了大量的三元,把第一版写的一堆if缩短到一行里了。
而页面组件刷新机制也是用state实现的,通过state控制for循环的起点和重点来控制输出数据的数量,即页数。
我的数据是以表格形式输出的。
var Class_All_TR=React.createClass({
getInitialState: function() {
return {page: 1};
},componentDidMount: function () {
this.pubsub_token = PubSub.subscribe('Change_Page', function (topic, page_num) {
this.setState({
page: page_num
});
}.bind(this));
},
componentWillUnmount: function () {
PubSub.unsubscribe(this.pubsub_token);
},
render: function() {
var sid="";
var rows=[]
//console.log(this.props.item);
var td_num=(this.state.page-1)*8;
for (var i = td_num; i < ((td_num+8)>Num_Class?Num_Class:(td_num+8)); i++) {
sid="_"+i;
rows.push(<Class_TR key={"TR__"+i} class_name={this.props.item[sid]["class_name"]} point={this.props.item[sid]["point"]} major={this.props.item[sid]["major"]} loc={this.props.item[sid]["loc"]} like={this.props.item[sid]["like"]} check={this.props.item[sid]["check"]} idi={i}/>);
}
Class_All_TR中的page属性控制了当前显示页面。
var td_num=(this.state.page-1)*8;
for (var i = td_num; i < ((td_num+8)>Num_Class?Num_Class:(td_num+8)); i++) {
这个就是控制显示的核心代码,这里是一页8个tr,即8个数据。
Class_TR组件是我的单个数据的组件,因为我的数据是显示在表格里的。
页面组件中比较重要的就是componentDidMount函数,其中订阅了‘Change_Page’消息,可以与Class_Foot组件通信,在Class_Foot组件更改其state:thispage并刷新自身Dom元素的时候通知Class_All_TR也更新page并刷新Dom元素。
关于组件之间的通信及PubSubJS的用法,请参考:http://www.tuicool.com/articles/AzQzEbq
这篇文章十分全面地讲解了组件之间的交互方式。
PS:setState函数会刷新组件的Dom元素,但是不会重新更新加载组件时传入的props数据,而如果你想更新他的props数据,你需要刷新的是使用该组件的Dom元素。