前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >写一个简单的轮播组件

写一个简单的轮播组件

作者头像
柴小智
发布2020-02-13 16:48:35
5710
发布2020-02-13 16:48:35
举报
文章被收录于专栏:菜鸟计划

直接上代码

代码语言:javascript
复制
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>
        )
    }
}
代码语言:javascript
复制
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;
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-01-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档