zoukankan      html  css  js  c++  java
  • 写一个简单的轮播组件

    直接上代码

    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 = {
               `${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;
      }
    }
  • 相关阅读:
    vue2.0 + vux (六)NewsList 资讯页 及 NewsDetail 资讯详情页
    vue2.0 + vux (五)api接口封装 及 首页 轮播图制作
    vue2.0 + vux (四)Home页
    vue2.0 + vux (三)MySettings 页
    vue2.0 + vux (二)Footer组件
    vue2.0 + vux (一)Header 组件
    vue2 + typescript2 自定义过滤器
    flexible.js + makegrid.js 自适应布局
    vue-router钩子beforeRouteEnter函数获取到this实例
    weex 项目搭建
  • 原文地址:https://www.cnblogs.com/chaixiaozhi/p/12191082.html
Copyright © 2011-2022 走看看