vue2轮播图组件

先上代码

原先使用DOM写的,转到vue暂时没去更改成ref

整体的效果实现,通过更改margin来显示切换图片的样式

<template>
    <div class="imgs">
        <div class="img" style="" v-for="(e, i) in imgUrl" :key="i">
      <img :src="https://juejin.cn/post/e" />
        </div>
      <div class="img">
            <img :src="https://juejin.cn/post/imgUrl[0]" />
        </div>
        <div class="btn-left" @click="btn_left"></div>
        <div class="btn-right" @click="btn_right"></div>
        <ul>
            <li @click="bt(i)" v-for="(e,i) in 6" :key="i"></li>
        </ul>
    </div>
</template>
<script>
export default {
    data() {
        return {
            r: true,
            ind: 0,
            imgs: document.getElementsByClassName("img"),
        };
    },
    props: ["imgUrl"],
    methods: {
        bt(e) {
            if (e !== this.ind) {
                if (e > this.ind) {
                    let o = e - this.ind;
                    console.log(o)
                    for (let i = 0; i < o; i++) {
                        this.imgs[this.ind].style.transition = ".5s";
                        this.imgs[this.ind].style.marginLeft = "-500px";
                        this.ind++;
                    }
                }
                if (e < this.ind) {
                    console.log('object')
                    let o = this.ind - e;

                    for (let i = 0; i < o; i++) {
                        this.imgs[this.ind - 1].style.transition = ".5s";
                        this.imgs[this.ind - 1].style.marginLeft = "0";
                        this.ind--;
                    }
                }
            }
        },
        btn_left() {
            if (this.r) {
                this.r = false;
                setTimeout(() => {
                    this.r = true;
                }, 1000);
                if (this.ind === 0) {
                    for (let i = 0; i < this.imgs.length - 1; i++) {
                        this.imgs[i].style.transition = "none";
                        this.imgs[i].style.marginLeft = "-500px";
                    }
                    this.ind = this.imgs.length - 1;
                    setTimeout(() => {
                        this.imgs[this.ind - 1].style.transition = ".5s";
                        this.imgs[this.ind - 1].style.marginLeft = "0";
                        this.ind--;
                    }, 100);
                } else {
                    this.imgs[this.ind - 1].style.transition = ".5s";
                    this.imgs[this.ind - 1].style.marginLeft = "0";
                    this.ind--;
                }
            }
        },
        btn_right() {
            if (this.r) {
                this.r = false;
                setTimeout(() => {
                    this.r = true;
                }, 1000);
                this.imgs[this.ind].style.transition = ".5s";
                this.imgs[this.ind].style.marginLeft = "-500px";
                this.ind++;
                if (this.ind == this.imgs.length - 1) {
                    setTimeout(() => {
                        for (let i = 0; i < this.ind; i++) {
                            this.imgs[i].style.transition = "none";
                            this.imgs[i].style.marginLeft = "0px";
                        }
                        this.ind = 0;
                    }, 600);
                }
            }
        },
    },
    computed: {},
};
</script>
<style scoped>
ul {
    display: flex;
    position: absolute;
    bottom: 0;
    width: 100%;
    flex-direction: row;
    justify-content: center;
}
li {
    z-index: 101;
    width: 20px;
    font-size: 40px;
}
img {
    width: 500px;
    height: 300px;
}
.imgs {
    height: 300px;
    position: relative;
    margin: 0 auto;
    overflow: hidden;
    display: flex;
    flex-direction: row;
    width: 500px;
}
.btn-left {
    position: absolute;
    top: 50%;
    left: 10px;
    border: 10px solid transparent;
    border-right: 20px solid #f00;
    width: 0;
    height: 0px;
}
.btn-right {
    position: absolute;
    top: 50%;
    right: 10px;
    border: 10px solid transparent;
    border-left: 20px solid #f00;
    width: 0;
    height: 0px;
}
</style>

复制代码

元素部分

imgs:代表父节点

img:每张图片

btn_left:左按钮

btn_right:右边按钮

ul > li:小圆点,可以设置成imgUrl.length

在样式中需要多放一张图片,实现最后一张图的无缝切换

<div class="imgs">
    <div class="img" style v-for="(e, i) in imgUrl" :key="i">
        <img :src="e" />
    </div>
 	 <div class="img">
            <img :src="imgUrl[0]" />
        </div>
    <div class="btn-left" @click="btn_left"></div>
    <div class="btn-right" @click="btn_right"></div>
    <ul>
        <li @click="bt(i)" v-for="(e,i) in 6" :key="i"></li>
    </ul>
</div>
复制代码

整体样式采用相对定位,通过固定宽度overflow: hidden达到效果

ul {
    display: flex;
    position: absolute;
    bottom: 0;
    width: 100%;
    flex-direction: row;
    justify-content: center;
}
li {
    z-index: 101;
    width: 20px;
    font-size: 40px;
}
img {
    width: 500px;
    height: 300px;
}
.imgs {
    height: 300px;
    position: relative;
    margin: 0 auto;
    overflow: hidden;
    display: flex;
    flex-direction: row;
    width: 500px;
}
.btn-left {
    position: absolute;
    top: 50%;
    left: 10px;
    border: 10px solid transparent;
    border-right: 20px solid #f00;
    width: 0;
    height: 0px;
}
.btn-right {
    position: absolute;
    top: 50%;
    right: 10px;
    border: 10px solid transparent;
    border-left: 20px solid #f00;
    width: 0;
    height: 0px;
}
复制代码

js实现

变量

ind:是现在的图片下标

imgs:获取所有图片的节点

r:节流开关

imgUrl:则是传入的图片地址

方法

bt():小圆点通过传入不同值来判断需要切换到第几章图片。

btn_left():往左边切换需要知道当前是不是第一张图,如果是第一张图则关闭动画,先切换到最后一张图片,然后开启动画,从最后一张切换到倒数第二张。

btn_rigth():往右切换的时候,只需要判断是否是最后一张,如果是最后一章则和向左切换最后一张的实现方法差不多。

两个点击按钮需要实现节流,防止用户多次点击,造成最后一张图片的空白。

两个按钮每次点击,向右需要将ind++向左则ind--,是为了确定当前图片是第几章。

因为,最后一张图片和第一张是相同的,实现的方式是让动画暂停,从最后一张回到第一张。

切换的很快,用户无法察觉效果以及完成。

快速切换使用的是for循环,通过给每一张添加marginLeft和marginLeft归零的方式进行,循环中length-1是因为,图片本来就是多一张用来无差别切换的。

圆点则是判断和当前位置相差几张,就循环几次添加。

export default {
    data() {
        return {
            r: true,
            ind: 0,
            imgs: document.getElementsByClassName("img"),
        };
    },
    props: ["imgUrl"],
    methods: {
        bt(e) {
            if (e !== this.ind) {
                if (e > this.ind) {
                    let o = e - this.ind;
                    console.log(o)
                    for (let i = 0; i < o; i++) {
                        this.imgs[this.ind].style.transition = ".5s";
                        this.imgs[this.ind].style.marginLeft = "-500px";
                        this.ind++;
                    }
                }
                if (e < this.ind) {
                    console.log('object')
                    let o = this.ind - e;

                    for (let i = 0; i < o; i++) {
                        this.imgs[this.ind - 1].style.transition = ".5s";
                        this.imgs[this.ind - 1].style.marginLeft = "0";
                        this.ind--;
                    }
                }
            }
        },
        btn_left() {
            if (this.r) {
                this.r = false;
                setTimeout(() => {
                    this.r = true;
                }, 1000);
                if (this.ind === 0) {
                    for (let i = 0; i < this.imgs.length - 1; i++) {
                        this.imgs[i].style.transition = "none";
                        this.imgs[i].style.marginLeft = "-500px";
                    }
                    this.ind = this.imgs.length - 1;
                    setTimeout(() => {
                        this.imgs[this.ind - 1].style.transition = ".5s";
                        this.imgs[this.ind - 1].style.marginLeft = "0";
                        this.ind--;
                    }, 100);
                } else {
                    this.imgs[this.ind - 1].style.transition = ".5s";
                    this.imgs[this.ind - 1].style.marginLeft = "0";
                    this.ind--;
                }
            }
        },
        btn_right() {
            if (this.r) {
                this.r = false;
                setTimeout(() => {
                    this.r = true;
                }, 1000);
                this.imgs[this.ind].style.transition = ".5s";
                this.imgs[this.ind].style.marginLeft = "-500px";
                this.ind++;
                if (this.ind == this.imgs.length - 1) {
                    setTimeout(() => {
                        for (let i = 0; i < this.ind; i++) {
                            this.imgs[i].style.transition = "none";
                            this.imgs[i].style.marginLeft = "0px";
                        }
                        this.ind = 0;
                    }, 600);
                }
            }
        },
    },
};
复制代码

轮播图实现的方法还有一种,通过单张图片的视口,然后所有图片拼成一张来回拉扯,但最后一张图片的实现大相径同,都是通过关闭动画时间实现的。

不喜勿喷,有想法可以提。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享