直接上代码
App.js文件
let list = [
{
id: 1,
img: require('./static/image/one.jpg')
},
{
id: 2,
img: require('./static/image/two.jpg')
},
{
id: 3,
img: require('./static/image/three.jpg')
}
];
render() {
return (
<div>
<Banner list={list}></Banner>
</div>
);
}
banner.js文件
import React from 'react';
import PropTypes from 'prop-types';
import {Button} from 'antd'
import '../static/css/banner.scss'
export default class Banner extends React.Component{
//设置默认值
static defaultProps = {
list: [],
interval: 3000,
}
//设置默认规则
static propTypes = {
list: PropTypes.array,
interval: PropTypes.number
}
//初始化状态值
constructor(){
super();
this.state = {
step: 1,
speed: '0.2s'
}
}
//组件挂载前进行数据预处理
componentWillMount() {
this.list = [this.props.list[this.props.list.length - 1], ...this.props.list, this.props.list[0]];
}
//组件挂载完成触发事件
componentDidMount() {
this.autoMove();
}
//组件更新前进行判断处理
componentWillUpdate(nextProps, nextState, nextContext) {
if (nextState.step >= this.list.length) {
this.setState({
step: 1,
speed: '0s'
});
}
if (nextState.step === -1) {
this.setState({
step: this.list.length - 2,
speed: '0s'
});
}
}
//组件完成更新进行判断处理
componentDidUpdate(prevProps, prevState, snapshot) {
if(this.state.step === 1 && this.state.speed === '0s'){
//js设置transition,不能在主栈队列执行时候遇到多次,这样渲染以最后一次为主,此时我们可以把第二次操作移动到EventQueue中。
let delayTimer = setTimeout(()=> {
this.setState({
step: this.state.step+1,
speed: '0.2s'
});
}, 50);
}
if (this.state.step === 3 && this.state.speed === '0s') {
let delayTimer = setTimeout(()=> {
this.setState({
step: this.state.step - 1,
speed: '0.2s'
});
}, 50);
}
}
autoMove = ()=> {
this.autoTime = setInterval(()=> {
this.setState({
step: this.state.step+1
})
}, this.props.interval)
}
handleClick = (e)=> {
if (e.target.tagName === 'BUTTON') {
let dir = e.target.getAttribute('dir');
this.setState({
step: dir === 'LEFT' ? this.state.step - 1 : this.state.step+1,
speed: '0.2s'
})
}
};
render() {
let wrapperStyle = {
width: `${this.list.length*1000}px`,
left: `${-this.state.step*1000}px`,
transition: `left ${this.state.speed} linear 0s`
};
return (
//利用事件委托统一处理
<div className={'banner_container'} onMouseEnter={event => {clearInterval(this.autoTime)}} onMouseLeave={this.autoMove} onClick={this.handleClick}>
<div className={'wrapper'} style={wrapperStyle}>
{
this.list.map((item,index) => {
let {img} = item;
return (
<div className={'slide'} key={index}>
<img src={img}/>
</div>
)
})
}
</div>
<Button dir={'LEFT'}>左</Button>
<Button dir={'Right'}>右</Button>
</div>
)
}
}
banner.scss文件
.banner_container{
margin: 20px auto;
width: 1000px;
height: 300px;
overflow: hidden;
position: relative;
.wrapper{
position: absolute;
left: 0;
top: 0;
width: 3000px;
height: 300px;
.slide{
font-size: 14px;
width: 1000px;
height: 300px;
line-height: 300px;
text-align: center;
float: left;
img{
background:no-repeat center;
width: 100%;
height: 100%;
}
}
}
button:nth-child(2){
position: absolute;
left: 0;
bottom: 0;
}
button:nth-child(3){
position: absolute;
right: 0;
bottom: 0;
}
}