移动端原生js封装轮播图和大图预览组件

vue2版本希望能帮到你 

首先看的是轮播图组件:

<template>

    <div class="swipe-banner">
        <div class="my-swipe">
            <div class="swipe_trank" style="width: 1500px;" ref="imgBox" @transitionend="animateEnd"
                @touchstart="TouchStart" @touchmove="TouchMove" @touchend="TouchEnd">
                <div class="swipe-item" style="width: 100vw">
                    <img src="http://43.138.15.137:4000//uploads/banner/9c3c5330-9267-11ee-9221-2175bc63238c.jpg"
                        v-if="imgfalg" class="img">
                    <img src="https://img14.360buyimg.com/n0/jfs/t1/131776/9/23287/325305/621f295fE9dc6a3ce/117b4d1ed262266a.jpg"
                        alt="" v-else>
                </div>
                <div class="swipe-item" style="width: 100vw;" v-for="item, index in swipeList" :key="index">
                    <img :src="'http://43.138.15.137:4000/' + item.img" v-if="imgfalg" class="img">
                    <img :src="item" alt="" v-else>
                </div>
                <div class="swipe-item" style="width: 100vw;">
                    <img src="  http://43.138.15.137:4000//uploads/banner/ed9d6b20-8f4b-11ee-9ff0-8d10ce4a0674.png"
                        v-if="imgfalg" class="img">
                    <img src="  http://43.138.15.137:4000//uploads/a68a96a0-8d29-11ee-9228-7b4607ce3ac3.jpg" v-else>
                </div>
            </div>
            <div class="swipe_indicators" v-if="imgfalg">
                <i class="swipe_indicator" v-for="item, index in swipeList" :key="index"
                    :class="{ 'swipe_indicator-active': index === circleIndex }"></i>
            </div>
        </div>
    </div>
    <!-- 轮播图 这个是轮播图的布局 在遍历轮播图数据的前后需要手动加上一图片,这样才能实现无缝轮播 -->
</template>
<script>
export default {
    // 因为是封装的组件,这个需要传递的参数,一个是轮播图的数据,另一个是小圆点的显示隐藏
    props: {
        swipeList: {
            type: Array
        },
        imgfalg: {
            type: Boolean,
            default: true
        }
    },
    data() {
        return {
            flag: true,   // 节流阀 防止快速滑动
            circleIndex: 0, // 当前展示图片对应圆点
            imgIndex: 0,   // 当前展示图片
            timer: null,   // 圆点定时器
            imgWidth: 0,   // 图片宽度
            startX: 0,    // 手指开始触摸位置
            moveX: 0,     // 手指移动距离
            interval: 2000, // 滚动间隔时间

        }
    },
    destroyed() {
        // 销毁dom元素的时候
        clearInterval(this.timer);
    },
    methods: {

        TouchStart(event) {
            clearInterval(this.timer)// 关闭自动轮播
            // 手指开始触摸事件
            if (this.flag) {
                // flag节流
                console.log(event.changedTouches[0].pageX);
                this.startX = event.changedTouches[0].pageX;// 获取开始触摸位置
            }
        },
        TouchMove(event) {// 手指开始移动
            console.log(event.changedTouches[0].pageX);
            if (this.flag) {
                this.moveX = event.changedTouches[0].pageX - this.startX // 手指移动位置
                this.$refs.imgBox.style = `transition: none;transform: translateX(${this.translatex + this.moveX}px);`
                //通过ref获取imbox然后获取手指的滑动距离 手指划过的距离加上图片ul当前距离
            }
        },
        TouchEnd(event) {
            if (this.moveX == 0) return
            // 结束触摸
            if (this.flag) {
                if (this.moveX > 80) {// 移动距离大于80,图片索引---
                    this.imgIndex--;
                    this.circleIndex--;
                } else if (this.moveX < -80) { // 移动距离小于-80,图片索引++
                    this.imgIndex++;
                    this.circleIndex++;
                }
                // 展示当前索引图片
                this.$refs.imgBox.style = `transition: all .5s;transform: translateX(${this.translatex}px);`
                // 触摸事件完成,继续自动轮播
                clearInterval(this.timer);
                // 防止定时器叠加
                if (this.imgfalg) {
                    this.timer = setInterval(() => {
                        this.imgIndex++;
                        this.circleIndex++;
                        this.$refs.imgBox.style = `transition: all .5s;transform: translateX(${this.translatex}px);`
                    }, this.interval);
                }
                this.$emit('zyj', this.circleIndex)
                this.flag = false; // 关闭节流阀,等待动画完成
            }
        },
        animateEnd() {
            // 事件在  动画完成时触发。如果在动画完成前中止了动画,将会把元素从 DOM 中移除,或将动画从元素上移除,animationend 事件不会触发。
            if (this.imgIndex >= this.swipeList.length) {// 判断当前图片索引是否为最后一张图
                this.imgIndex = 0;
                // 当前展示图片
                this.$refs.imgBox.style = `transition: none;transform: translateX(-${this.imgWidth}px);`
            }
            if (this.imgIndex < 0) { // 判断当前图片索引是否为第一张图
                this.imgIndex = this.swipeList.length - 1;
                this.$refs.imgBox.style = `transition: none;transform: translateX(${this.translatex}px);`
            }
            this.flag = true;
        },
    },
    computed: {
        translatex() {
            // 计算图片ul当前距离
            return -(this.imgWidth + this.imgWidth * this.imgIndex);
            // 图片的宽成语滑动了几张图片成语滑动了几张图片 
            // 变成负数是看他划了多少距离
        }
    },
    mounted() {
        let that = this
        window.addEventListener('resize', () => {
            that.imgWidth = window.innerWidth;
            document.querySelectorAll('.swipe-item').forEach((item) => {
                item.style = `width: ${that.imgWidth || window.innerWidth}px;`
            })

        })
        this.imgWidth = window.innerWidth;// 获取图片宽度
        console.log(window.innerHeight, 'yutr');
        // 先左移动一个图片距离,显示第一张图片
        this.$refs.imgBox.style = `transform: translateX(-${this.imgWidth}px);`
        if (this.imgfalg) {
            this.timer = setInterval(() => {
                this.imgIndex++;
                this.circleIndex++;// 自动轮播

                this.$refs.imgBox.style = `transition: all .5s;transform: translateX(${this.translatex}px);`// 切换下一张图片
            }, this.interval)
        }
    },
    watch: {
        circleIndex() {
            // 监视原点索引变化
            if (this.circleIndex >= this.swipeList.length) {
                this.circleIndex = 0;
            }
            if (this.circleIndex < 0) {
                this.circleIndex = this.swipeList.length - 1;
            }
        }
    },
}
</script>
<style scoped lang="scss">
$rem: 37.5;
.swipe-banner {
    margin: (2.5rem / $rem) 0;

    .my-swipe {
        position: relative;
        overflow: hidden;
        transform: translateZ(0);

        .swipe_trank {
            display: flex;
            height: 100%;
            align-items: center;

            .swipe-item {
                position: relative;
                flex-shrink: 0;
                height: 100%;

                img {
                    width: 100%;

                }

                .img {
                    height: 200rem / $rem;
                }
            }
        }

        .swipe_indicators {
            position: absolute;
            bottom: 12rem / $rem;
            left: 50%;
            display: flex;
            transform: translateX(-50%);

            .swipe_indicator {
                width: 6rem / $rem;
                height: 6rem / $rem;
                margin-right: 6rem / $rem;
                background-color: #ebedf0;
                border-radius: 100%;
                opacity: 0.3;
            }

            .swipe_indicator-active {
                background-color: white;
                opacity: 1;
            }
        }
    }
}

.borders {
    background-color: rgb(255, 255, 255);
    transform: translateX(69px) translateX(-50%);
    transition-duration: 0.3s;
}

.home[data-v-3dd2e005] {
    min-height: 100vh;
    background: #EEE;
}

.nav[data-v-65221434] {
    width: 100vw;
    height: 1.06667rem;
    line-height: 1.06667rem;
    text-align: center;
    background: #FF6040;
    color: white;
    position: fixed;
    top: 0;
    left: 0;
    font-size: 0.4rem;
    z-index: 100;
}

.back[data-v-65221434] {
    position: absolute;
    left: 0.26667rem;
}

.head[data-v-3dd2e005] {
    width: 100%;
    height: 2.33333rem;
    background: linear-gradient(#FF6040, #FF8A80);
}

.search[data-v-3dd2e005] {
    height: 1.06667rem;
    width: 100%;
    display: flex;
    justify-content: space-around;
    align-items: center;
}

.search img[data-v-3dd2e005]:nth-of-type(1) {
    width: 0.53333rem;
    height: 0.58667rem;
}

.search .search_input[data-v-3dd2e005] {
    width: 4.53333rem;
    height: 0.85333rem;
    background-color: white;
    border-radius: 0.10667rem;
    padding: 0.06667rem 0.26667rem;
    box-sizing: border-box;
}

.van-field[data-v-3dd2e005] {
    padding: 0;
    width: 80%;
    font-size: 0.30667rem;
}

.van-cell {
    position: relative;
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    box-sizing: border-box;
    width: 100%;
    padding: 0.26667rem 0.42667rem;
    overflow: hidden;
    color: #323233;
    font-size: 0.37333rem;
    line-height: 0.64rem;
    background-color: #fff;
}

.van-field__left-icon {
    margin-right: 0.10667rem;
}

.van-field__left-icon .van-icon,
.van-field__right-icon .van-icon {
    display: block;
    font-size: 0.42667rem;
    line-height: inherit;
}

.van-icon {
    position: relative;
    display: inline-block;
    font: normal normal normal 0.37333rem / 1 vant-icon;
    font-size: inherit;
    text-rendering: auto;
    -webkit-font-smoothing: antialiased;
}

.van-icon-search:before {
    content: '\e710';
}

.van-icon:before {
    display: inline-block;
}

.search img[data-v-3dd2e005]:nth-of-type(2) {
    width: 2.42667rem;
    height: 0.64rem;
}

.dp[data-v-3dd2e005] {
    width: 0.53333rem;
    height: 0.53333rem;
}

.cate[data-v-3dd2e005] {
    display: flex;
}

.catenavtab[data-v-3dd2e005] {
    width: 8.26667rem;
}

.van-tabs {
    position: relative;
}

.van-tabs--line .van-tabs__wrap {
    height: 1.17333rem;
}

.van-tabs__wrap {
    overflow: hidden;
}

.van-tabs__nav--line.van-tabs__nav--complete {
    padding-right: 0.21333rem;
    padding-left: 0.21333rem;
}

.van-tabs__wrap--scrollable .van-tabs__nav {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
}

.van-tabs__nav--line {
    box-sizing: content-box;
    height: 100%;
    padding-bottom: 0.4rem;
}

.van-tabs__nav {
    position: relative;
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    background-color: #fff;
    -webkit-user-select: none;
    user-select: none;
}

.van-tabs__wrap--scrollable .van-tab {
    -webkit-box-flex: 1;
    -webkit-flex: 1 0 auto;
    flex: 1 0 auto;
    padding: 0 0.32rem;
}

.van-tab--active {
    color: #323233;
    font-weight: 500;
}

.van-tab {
    position: relative;
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    -webkit-box-flex: 1;
    -webkit-flex: 1;
    flex: 1;
    -webkit-box-align: center;
    -webkit-align-items: center;
    align-items: center;
    -webkit-box-pack: center;
    -webkit-justify-content: center;
    justify-content: center;
    box-sizing: border-box;
    padding: 0 0.10667rem;
    color: #646566;
    font-size: 0.37333rem;
    line-height: 0.53333rem;
    cursor: pointer;
}

.category[data-v-3dd2e005] {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 1.73333rem;
}

.category img[data-v-3dd2e005] {
    width: 0.34667rem;
    height: 0.37333rem;
}

.category span[data-v-3dd2e005] {
    margin-left: 0.2rem;
    color: white;
    font-size: 0.34667rem;
}

.swiper_banner[data-v-3dd2e005] {
    margin: 0.06667rem 0;
}

.van-swipe {
    position: relative;
    overflow: hidden;
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    cursor: grab;
    -webkit-user-select: none;
    user-select: none;
}

.van-swipe__track {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    height: 100%;
}

.my-swipe .van-swipe-item[data-v-3dd2e005] {
    color: #fff;
    font-size: 0.26667rem;
}

.van-swipe-item {
    position: relative;
    -webkit-flex-shrink: 0;
    flex-shrink: 0;
    width: 100%;
    height: 100%;
}

.van-swipe-item img[data-v-3dd2e005] {
    width: 100%;
    height: 5.33333rem;
}

.lpops {
    display: flex;
}

.apsaa {
    width: 100%;
    height: 20rem;

    position: relative;
}

li.title {
    flex: 1;
    text-align: center;
    height: 0.9rem;
    line-height: 0.9rem;
    font-size: 0.4rem;
    cursor: pointer;
}

.ols {
    color: gray;
    font-size: 1.8rem;

}

.active {
    color: #FFF;
    background: #FFA500;
}


.con-active {
    display: block;
}


.ddds[data-v-12beccd8] {
    width: 14rem;

    font-size: 0.5rem;
    margin-top: 1rem;
    margin-bottom: 3rem;
}

.dddd {
    width: 3rem;
    font-size: 1.2rem;
    color: black;
}

.lss[data-v-12beccd8] {
    width: 3rem;
    height: 0.8rem;
    margin-top: 7rem;
    font-size: 0.2rem;
    color: white;
    text-align: center;
    background-color: #FF6040;
    border: none;
}

.dyx {
    float: left;
    height: 3rem;
    background-color: red;

}

.dyx2 {
    float: left;
    height: 0.1rem;

}

.dyx3 {
    float: left;
    height: 10rem;

}
</style>

然后就是如何使用:在父组件直接使用即可

  <lunbotu :swipeList="swipeList"></lunbotu>

用法就是先引入你的轮播图组件:里面的swipeList是你在父组件通过接口拿到的轮播图数据然后在子传父穿过去渲染就行了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值