<template>
<div>
<div class="swiper_container">
<div :class="index==0||index==-1?'noAnimate':'animate'" class='swiper_content' ref="swiperRef" :style="{transform:`translateX(${scrollWin}px)`}">
<div class="swiper_item" v-for="(item,index) in imgs" :key="index">
<img :src="item.img" alt="">
</div>
</div>
<div class="dots_wrap">
<span :class="index==idx?'active':''" class="dot" v-for="(item,idx) of imgs1.length" :key="idx"></span>
</div>
<span class="left_btn" @click="clickLeft">left</span>
<span class="right_btn" @click="clickRight">right</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, toRefs, onMounted, } from 'vue'
const swiperRef=ref(null)
let w=ref(800)
let scrollWin=ref(0)
const imgs1=[
{id:"001",img:new URL("../assets/imgs/1.png",import.meta.url).href},
{id:"002",img:new URL("../assets/imgs/2.png",import.meta.url).href},
{id:"003",img:new URL("../assets/imgs/3.png",import.meta.url).href},
{id:"004",img:new URL("../assets/imgs/4.png",import.meta.url).href},
{id:"005",img:new URL("../assets/imgs/5.png",import.meta.url).href},
]
let imgs=ref([...imgs1])
// imgs.value.push(imgs1[0],imgs1[1])
const firstimg=imgs.value[0]
const lastimg=imgs.value[imgs.value.length-1]
onMounted(() => {
})
const index=ref(0)
const clickLeft=()=>{
index.value--;
console.log("index.value",index.value)
if(index.value<=-1){
scrollWin.value=-w.value*imgs.value.length
console.log("w.value",w.value)
console.log("imgs.value",imgs.value.length)
console.log("scrollWin.value",scrollWin.value)
setTimeout(()=>{
index.value=4
scrollWin.value=-index.value*w.value;
},0)
}else{
scrollWin.value=-index.value*w.value;
}
}
const clickRight=()=>{
index.value++;
console.log("index.value",index.value)
console.log("index.value",index.value)
if(index.value>=5){
setTimeout(()=>{
imgs.value.push(firstimg)
console.log("imgs---prev",imgs)
index.value=0;
scrollWin.value=0
console.log("imgs--next",imgs)
},200)
}
console.log("ndex.value*w.value",index.value,w.value)
scrollWin.value=-index.value*w.value;
// swiperRef.value.style.transform=`translateX(${w}px)`
// debugger
}
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
.swiper_container{
width: 800px;
height: 320px;
margin: 0 auto;
position: relative;
overflow: hidden;
}
.swiper_content{
display: flex;
position: absolute;
top:0;
left:0;
height: 100%;
}
.dots_wrap{
position: absolute;
bottom: 0;
width: 50%;
left:50%;
transform: translate(-50%,-50%);
text-align: center;
}
.swiper_item{
width: 800px;
margin: 0;
}
.swiper_item img{
width: 100%;
height: 100%;
object-fit: cover;
}
.dot{
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
z-index: 1;
background: #fff;
margin: 0 10px;
}
.active{
background: #f90;
}
.left_btn,.right_btn{
display: inline-block;
width: 60px;
height: 42px;
background: #000;
color:#fff;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.left_btn{
position: absolute;
top:50%;
left:20px;
}
.right_btn{
position: absolute;
top:50%;
right:20px
}
.noAnimate{
transition: none;
}
.animate{
transition: all 0.2s;
}
.active{
color:#f00
}
</style>
在第一张图片和最后一张图片无缝切换的思路就是在原来数据的尾部添加一张第一张图片,然后通过scrollWin.value=0迅速让整个container回到left为0的位置。为了避免此时第二张图大幅度回滚效果,我们先把transition动画取消,也就是通过:class="index==0||index==-1?'noAnimate':'animate'" 来控制。先不让其有动画,回到初始位置以后再进行动画设置