Vue案例:图片轮播图
轮播图应该是在学编程的时候经常遇到的组件,在我看来一个轮播图的好坏在于代码是否简洁易懂,滑动的时候是否流畅,不卡顿,这样才算是一个好的轮播图。
最近也写了一个,直接上图看效果:
点击左右的两个箭头按钮可以来回切换图片,下方的小圆点对应着图片的位置,处于哪张图片,哪个小圆点就会变成长条状的。
实现间隔3秒切换一下的效果,我用的是一个定时器setInterval,在渲染完页面后就会隔3秒执行一次next函数。
next() {
this.translateX++
this.tsion = true
if (this.translateX > this.src.length - 1) {
setTimeout(() => {
this.tsion = false
this.translateX = 0
}, 500)
}
}
},
mounted() {
setInterval(()=>{
this.next()
},3000)
},
如何做到不卡顿或是在最后一张的时候回去和第一张衔接呢?
我的处理方法是在第一张图片的前面插入最后一张图片,在最后一张图片插入第一张图片,这样等到了最后一张图片的时候,再点击向下就会跳到第一张图片,当js检测移动到超出data里src属性的图片路径的行为时,就会关闭transition过渡属性,然后跳转到data里src属性的第一张图片这里,然后在循环开始时把transition过渡属性加回去。
<div class="show-box" :style="{'transform':'translateX('+translate+'px)','transition':tsion?'all 0.5s':'none'}">
<img src="./images/8.jpg" alt="">
<img v-for='(item,index) in src' :src="item" alt="">
<img src="./images/1.jpg" alt="">
</div>
// 上一张
last() {
this.translateX--
this.tsion = true
if (this.translateX < 0) {
setTimeout(() => {
this.tsion = false
this.translateX = this.src.length - 1
}, 500)
}
},
// 下一张
next() {
this.translateX++
this.tsion = true
if (this.translateX > this.src.length - 1) {
setTimeout(() => {
this.tsion = false
this.translateX = 0
}, 500)
}
},
这是全部的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片轮播图</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div id="app">
<div class="big-box">
<div class="img-box">
<div class="show-box" :style="{'transform':'translateX('+translate+'px)','transition':tsion?'all 0.5s':'none'}">
<img src="./images/8.jpg" alt="">
<img v-for='(item,index) in src' :src="item" alt="">
<img src="./images/1.jpg" alt="">
</div>
</div>
<div class="arrowhead-box">
<span @click='last'></span>
<span @click='next'></span>
</div>
<div class="swiper-box" ref="swiper">
<span v-for='(item,index) in src' @click='swiper(index)'></span>
</div>
</div>
</div>
<script src="../../js/vue.js"></script>
<script src="./js/index.js"></script>
</body>
</html>
body {
margin: 0;
padding: 0;
background-image: linear-gradient(to top, #37ecba 0%, #72afd3 100%);
}
span {
margin: 0;
padding: 0;
}
.big-box {
width: 650px;
height: 400px;
background-color: #999;
margin: 100px auto;
position: relative;
box-shadow: 0 0 3pc rgba(0, 0, 0, 0.4);
}
.img-box {
width: 100%;
height: 100%;
overflow: hidden;
}
.show-box {
display: flex;
height: 100%;
width: 100%;
transition: all 0.5s;
}
.show-box img {
float: left;
min-width: 650px;
min-height: 400px;
}
.arrowhead-box {
position: absolute;
top: 40%;
float: left;
width: 100%;
height: 50px;
}
.arrowhead-box span {
float: left;
display: block;
width: 60px;
height: 60px;
border-radius: 50px;
background:url('../images/last.png') no-repeat;
background-color: rgba(0, 0, 0, 0.4);
background-position: 6px 14px;
cursor: pointer;
opacity: 0.5;
}
.arrowhead-box span:nth-child(2) {
float: right;
transform:rotate(180deg);
}
.arrowhead-box span:hover {
opacity: 1;
}
.swiper-box {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.swiper-box span {
float: left;
width: 12px;
height: 12px;
background-color: white;
border-radius: 50px;
margin-left: 10px;
cursor: pointer;
transition: all 0.5s ease-out;
}
.swiper-box span:nth-child(1) {
width: 100px;
}
Vue.config.productionTip = false
new Vue({
el: '#app',
data: {
src: ['./images/1.jpg', './images/2.jpg', './images/3.jpg', './images/4.jpg',
'./images/5.jpg', './images/6.jpg', './images/7.jpg', './images/8.jpg'
],
translateX: 0,
tsion: true
},
methods: {
// 上一张
last() {
this.translateX--
this.tsion = true
if (this.translateX < 0) {
setTimeout(() => {
this.tsion = false
this.translateX = this.src.length - 1
}, 500)
}
},
// 下一张
next() {
this.translateX++
this.tsion = true
if (this.translateX > this.src.length - 1) {
setTimeout(() => {
this.tsion = false
this.translateX = 0
}, 500)
}
},
swiper(i){
this.translateX = i
}
},
mounted() {
setInterval(()=>{
this.next()
},3000)
},
computed: {
translate() {
return -(this.translateX + 1) * 650
}
},
watch: {
translateX: {
handler(val) {
let a = this.$refs.swiper.querySelectorAll('span')
a.forEach(element => {
element.style.width = '12px'
});
if (this.translateX < 0) {
val = this.src.length - 1
}
if (this.translateX > this.src.length - 1) {
val = 0
}
a[val].style.width = '100px'
},
}
}
})
发表评论 (审核通过后显示评论):