<template>
<div class="swiperLoop">
<div :style="{'width':width,'height':height}" class="swiper">
<ul class="swiper-ul">
<li
:class="['swiper-ul-li',{'active':active === index}]"
v-for="(item,index) in list"
:key="item.id"
:style="{'height':'80px','width': active === index ?`calc(${100 / showNum}% - 14px)`:`calc(${100 / showNum}% - 10px)`}"
@click="handelActive(index)"
>
<img
:src="item._src"
style="width: 100%; height: 100%"
>
</li>
</ul>
<i class="el-icon-arrow-left btn-l btn" @click="onLeftMove"></i>
<i class="el-icon-arrow-right btn-r btn" @click="onRightMove"></i>
</div>
</div>
</template>
<script>
export default {
name: 'SwiperLoop',
props: {
list: {
type: Array,
default: () => []
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '100%'
},
showNum: {
type: Number,
default: 4
}
},
data() {
return {
active: 0,
moveI: 0
};
},
mounted(){
},
methods: {
handelActive(index){
this.active = index;
},
onLeftMove() {
const len = this.list.length;
let type = 'muinus';
if (this.active <= 0) {
this.active = len - 1;
this.moveI = len - this.showNum;
type = 'mHoming';
} else {
this.active -= 1;
type = 'muinus';
}
this.docMove(type);
},
onRightMove() {
const len = this.list.length - 1;
let type = 'add';
if (this.active >= len) {
this.active = 0;
this.moveI = 0;
type = 'addHoming';
} else {
this.active += 1;
type = 'add';
}
this.docMove(type);
},
async docMove(type) {
await this.$nextTick()
let { active } = this;
let len = this.list.length;
let ul = document.querySelector('.swiper-ul');
let li = document.querySelector('.swiper-ul>li');
let ulw = Math.floor(ul.offsetWidth);
let liw = Math.floor(li.offsetWidth);
if (liw * (active + 1) >= ulw && active < len && type === 'add') {
this.moveI += 1;
ul.style.transform = `translateX(-${(liw + 10) * this.moveI}px)`;
}
if (type === 'addHoming') {
ul.style.transform = `translateX(0)`;
}
if (type === 'mHoming') {
ul.style.transform = `translateX(-${(liw + 10) * this.moveI}px)`;
}
if (type === 'muinus') {
this.moveI = this.moveI > 0 ? (this.moveI -= 1) : 0;
ul.style.transform = `translateX(-${(liw + 10) * this.moveI}px)`;
}
this.$emit('swiperActive', active);
}
}
};
</script>
<style lang="scss" scoped>
ul,
li {
list-style: none;
padding: 0;
margin: 0;
}
.swiperLoop {
width: 100%;
height: 100%;
position: relative;
.swiper {
margin: 10px auto;
overflow: hidden;
.swiper-ul {
height: 100%;
display: flex;
flex-wrap: nowrap;
transition: all 0.5s;
.swiper-ul-li {
flex-shrink: 0;
height: 100%;
margin-left: 10px;
border: 2px;
}
li:nth-child(1) {
margin-left: 0;
}
.active {
height: calc(100% - 4px);
border: 2px solid #22b0ab;
}
}
.btn {
font-size: 38px;
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
}
.btn-l {
left: 0px;
}
.btn-r {
right: 10px;
}
}
}
</style>
思路:
获取一个li的宽度,获取ul的宽度,记录一个移动下标值moveI,设置一个当前下标active。ul的宽度是固定的。
当向右点击时active加等于1,判断active乘以li的宽是否大于等于ul的宽,如果大于moveI加等于1,让ul移动,移动的距离是li的宽乘以moveI。
当向左点击是active减等于1,moveI也跟着减等于1。moveI不能小于0。
当active小于0时,让active等于list.length-1,让moveI等于list.length-1减去展示图的数量showNum。