<template>
<div class="swipper-container">
<span class="swiper-btn" @click="handlerLeftClick">《</span>
<div class="inner-box" ref="showAreaRef">
<div
class="item-group"
:style="{
left: groupPosLeft + 'px',
}"
ref="ItemGroupRef"
>
<div class="s-item" v-for="item in 40" :key="item.id">
{{ item }}
</div>
</div>
</div>
<span class="swiper-btn" @click="handlerRightClick">》</span>
</div>
</template>
<script>
export default {
data() {
return {
groupPosLeft: 0,
dataList: [],
showAreaRef: null,
ItemGoupRef: null,
}
},
methods: {
handlerLeftClick() {
this.calcMove(false)
},
handlerRightClick() {
this.calcMove(true)
},
calcMove(isRight = true) {
const radix = isRight ? -1 : 1
/**
* 这里考虑到放入的父盒子可能是响应式的,
* 可能点击了之后,窗口大小发生过变化,影响计算结果,
* 所以考虑每次点击都获取最新的显示区域的宽度
*/
// 显示区域宽度
const showAreaWidth = this.$refs.showAreaRef.offsetWidth
//
// 展示项的父盒子宽度(这个宽度相对来说比较固定,可以在自己挂载时获取一次就行了,后边自己优化一下)
const ItemGroupWidth = this.$refs.ItemGroupRef.offsetWidth
// 剩余部分的宽度
const restWidth = isRight ? ItemGroupWidth - (Math.abs(this.groupPosLeft) + showAreaWidth) : Math.abs(this.groupPosLeft)
console.log(showAreaWidth, ItemGroupWidth, restWidth)
if (restWidth <= 0) return false
// 如果剩余部分大于显示区域则移动一屏,否则移动剩余部分的宽度
if (restWidth / showAreaWidth >= 1) {
// 为了让上一屏被压住的子项 移动后对齐 (80为 一个子项的宽度 + 一个padding)
const x = Math.floor(showAreaWidth / 80) * 80
this.groupPosLeft = this.groupPosLeft + radix * x
} else {
this.groupPosLeft = this.groupPosLeft + radix * restWidth
}
},
},
}
</script>
<style lang="less" scoped>
@swipperHeight: 80px;
.swipper-container {
display: flex;
width: 100%;
height: @swipperHeight;
box-sizing: border-box;
border: 1px solid rgb(3, 86, 77);
.swiper-btn {
background: rgb(3, 86, 77);
display: inline-block;
text-align: center;
width: 30px;
line-height: @swipperHeight;
}
.inner-box {
flex-grow: 1;
position: relative;
overflow: hidden;
.item-group {
position: absolute;
box-sizing: border-box;
top: 0;
left: 0;
padding: 0 10px;
display: flex;
height: @swipperHeight;
overflow: hidden;
align-items: center;
transition: all 0.5s linear;
}
}
.s-item {
width: 70px;
height: 70px;
background: rgb(10, 130, 130);
& + .s-item {
margin-left: 10px;
}
}
}
</style>