这一节,我们来看一个banner图轮播,banner图轮播是一个比较常用的需求,而且几乎每个网站,每个app都会有一个banner图轮播的效果,也不知道是谁创造出来的。
1、banner图一般都是从文件服务器获取的,也就是需要发请求获取数据,需要发ajax请求,这里我们需要使用jquery,当然,你也可以写个原生的HTTPRequest那个原生写法。
继续打开小黑窗,输入npm install jquery --save-dev,
等下载成功后,看一眼“node_modules”文件夹下,是不是已经有“jquery”这个文件夹了,如果有了那么我们就可以在项目中使用jquery的相应功能了,如果还没有说明没有下载成功
2、我加上我写的样式,仍然是写到demo.css中了
.banner{position:relative;}
ul{list-style:none;height:150px;overflow:hidden;width:100%;padding:0;margin:0;}
ul li{width:100%;height:150px;opacity:0;z-index:0;display:block;position:absolute;}
.li_show{
display:block;
animation:litoshow 2s 1;
animation-fill-mode: forwards;
-webkit-animation:litoshow 2s 1;
-webkit-animation-fill-mode: forwards;
}
@keyframes litoshow{
0% {display:none;}
100% {display:block;opacity:1;z-index:1;}
}
@-webkit-keyframes litoshow{
0% {display:none;}
100% {display:block;opacity:1;z-index:1;}
}
ul li img{width:100%;height:150px;}
.ban_btn{position:absolute;top:60px;width:100%;}
.ban_btn>div{width:35px;height:35px;background:#0863BC;border-radius:5px;text-align:center;line-height:35px;font-size:20px;color:#FFF;z-index:2;}
.ban_btn>div:nth-child(1){position:relative;}
.ban_btn>div:nth-child(2){float:right;position:relative;top:-36px;}
这里面我们着重看li_show这个类,先记下来,后面会用到,这里可以看出是给一个css类添加了css3 animation动画即可
3、index.js中
引入我们第一步下载的jquery
代码:import $ from 'jquery';
4、首页组件包装,继续修改index.js:
var SiteIndex = React.createClass({
render: function(){
return (
<div>
<AppTop word="首页"/>
<BnanerSwipe />
</div>
);
}
});
AppTop我们认识,是上一节说过的顶部栏,现在多添加了一个BannaerSwipe组件
5、index.js中添加BannaerSwipe组件实现:
var BnanerSwipe = React.createClass({
getInitialState: function() {
return {
"bd": [],
"length": 0,
"index": 0
};
},
componentDidMount: function () {
$.post('http://www.xxx.com/prd/api/bannerPage', {},
function (data) {
this.setState({
bd: data["data"]["homeCarouselList"],
length: data["data"]["homeCarouselList"].length
});
}.bind(this));
},
prevImg: function(){
var index = this.state.index, l = this.state.length;
index--;
index = (index==-1) ? (l - 1) : index;
this.setState({"index":index}, () => this.state.index = index);
},
nextImg: function(){
var index = this.state.index, l = this.state.length;
index++;
index = (index==4) ? 0 : index;
this.setState({"index":index}, () => this.state.index = index);
},
render: function(){
var bannerImg = this.state.bd, index = this.state.index;
if(bannerImg.length == 0){
return false;
}
return (
<div className="banner">
<ul>
{bannerImg.map(function(v, k){
return (
<li key={k} className={index==k ? "li_show" : ""}>
<img src={v.imageUrl} />
</li>
);
})}
</ul>
<div className="ban_btn">
<div onClick={this.prevImg}>←</div>
<div onClick={this.nextImg}>→</div>
</div>
</div>
);
}
});
getInitialState这个方法是初始化定义组件中需要的一些配置变量,db是用来预备存放banner图数据的,length用来预备存放banner图的个数,index是用来标记当前banner图显示索引;
componentDidMount这个方法是准备数据的,里面我们放了一个jquery的ajax用来请求数据,然后使用this.setState方法更改初始化的预存变量来为我们后续使用;
prevImg nextImg 这两个事件后面可以找到调用事件的地方,就是onClick,这个没有问题呗,但this.setState这个方法中,我们除了给组件的satate赋值,还添加了第二个函数 () => ,这个因为this.setState方法有异步性,第一次赋值不能及时挂到组件的state上,需要添加个回调函数,这样我们set的属性值就可以及时被我们使用啦;
render 这个方法中,bannerImg是我们请求到的图片数据,通过map来遍历显示,看到map你能想到for循环就可以了,然后你去看一下es6的map方法的使用,react的map遍历,你可以看见,我们给li加了key属性,这个是必须要的,也没什么实际意义,就是为了区分每条数据,然后根据当前索引值来判断给哪一个li添加li_show样式,然后我们在第1条中说过li_show这个样式,其实就是一个小的css3显示效果,通过这样一个过程达到banner图循环显示的效果。
其实我们这个插件并非轮播,但现在互联网上这种隐藏淡入的方式也挺流行的,所以我就顺手做了一个淡入淡出的banner图展示,你如果看明白了这个,轮播的效果几乎也挺好实现的。
6、banner图效果如图:
因为请求的banner图可能会有盗图嫌疑,所以我涂鸦了,你能看清这是个banner图就可以了,然后有左右两个控制按钮。
7、banner图效果实现出来了,从这个简单的例子其实我们就可以看出React组件的大概生命周期了,下一节我们通过这个例子说一下生命周期的问题,喜欢的小伙伴请关注下一节:狗屎一样的React(第五节,React组件的生命周期)