效果
<!-- 上下滑动轮播图片查看 -->
<template>
<div class="collection-preview">
<div class="img-list">
<div class="left-prev" @click="onPrev" :style="{ cursor: imgIndex > 0 ? 'pointer' : 'not-allowed' }" style="border: 1px solid;">
<i class="el-icon-arrow-left"></i>
</div>
<div class="right-next" @click="onNext" :style="{ cursor: imgIndex < imgList.length - 1 ? 'pointer' : 'not-allowed' }" style="border: 1px solid;">
<i class="el-icon-arrow-right"></i>
</div>
<ul class="img-container" ref="imgContainer">
<li v-for="(item1, index) in imgList" :key="index" :class="[imgIndex === index ? 'active' : '']" :style="{
zIndex: `${positionList[index].zIndex}`,
transform: `translateY(${positionList[index].translateY}px) scale(${positionList[index].scale})`,
top: imgIndex === index ? elTop + 'px' : '0px',
}" @touchstart="(e) => onTouchStart(e, index)" @touchmove="onTouchmove" @touchend="onTouchend">
<img :src="item1" v-show="index < 3" alt="" />
</li>
<li v-if="imgList.length === 0">暂无数据</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'BannerPreview',
props: {
// 图片数据,数组的值直接放图片链接就行了
imgData: {
type: Array,
default: [],
},
},
data() {
return {
// 当前展示的图片
imgUrl: '',
// 图片列表数据
imgList: [],
// 图片位置数据
positionList: [],
// 当前选中的图片下标
imgIndex: 0,
// 滑动初始top位置
touchTop: 0,
// 元素最终top位置
elTop: 0,
// 最大拖拽值
touchMax: 50,
};
},
watch: {
// 监听图片数据
imgData: {
immediate: true, // 及时监听
handler(newValue, oldValue) {
if (newValue === oldValue || !newValue) {
return;
}
this.imgList = [...newValue];
this.setPositionList();
},
},
},
created() { },
mounted() { },
methods: {
/**
* 功能函数 *
*/
// 设置定位值
setPositionList() {
this.positionList = this.imgList.map((el, index) => {
// 图片缩放系数,以1为初始值
let scale = 1 - 0.1 * index;
// 图片向上偏移系数
let top = -30;
return {
scale,
zIndex: 100 - index,
translateY: top * index * scale,
};
});
},
// 上一个
onPrev() {
let pop = this.positionList.shift();
this.positionList.push(pop);
},
// 下一个
onNext() {
let pop = this.positionList.pop();
this.positionList.unshift(pop);
},
// 拖拽开始
onTouchStart(e, index) {
// 目标事件
let touch = e.targetTouches[0];
// 目标元素
let el = e.target;
this.imgIndex = index;
// 记录目标元素原始位置
this.touchTop = touch.clientY - el.offsetTop;
document.addEventListener('touchmove', this.defaultEvent, false);
},
// 拖拽移动
onTouchmove(e) {
// 目标事件
let touch = e.targetTouches[0];
let oTop = touch.clientY - this.touchTop;
if (oTop < -this.touchMax) {
oTop = -this.touchMax;
} else if (oTop >= this.touchMax) {
oTop = this.touchMax;
}
// 减小一倍拖动阻力
this.elTop = oTop * 2;
document.addEventListener('touchmove', this.defaultEvent, false);
},
// 拖拽移动事件移除
onTouchend() {
if (this.elTop < -this.touchMax) {
this.onPrev();
} else if (this.elTop > this.touchMax) {
this.onNext();
}
this.elTop = 0;
document.removeEventListener('touchmove', this.defaultEvent);
},
//阻止默认事件
defaultEvent(e) {
e.preventDefault();
},
},
};
</script>
<style lang="less" scoped>
.collection-preview {
position: absolute;
top: 10%;
left: 0;
width: 100%;
height: 90%;
z-index: 1000;
.img-list {
margin-top: 20px;
width: 100%;
height: 80vh;
position: relative;
.left-prev,
.right-next {
position: absolute;
top: 50%;
height: 50px;
width: 50px;
text-align: center;
font-size: 40px;
cursor: pointer;
color: #ddd;
z-index: 1000;
&:hover,
&.active {
color: #999;
}
}
.left-prev {
left: 0;
}
.right-next {
right: 0;
}
ul {
width: 100%;
height: 100%;
position: relative;
li {
width: 90%;
height: 86%;
border-radius: 10px;
transition: 0.5s;
cursor: pointer;
overflow: hidden;
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: auto;
transform-origin: center top;
&.active {
box-shadow: 1px 1px 10px #999;
}
img {
width: 100%;
height: 100%;
}
}
}
}
}
</style>