vue的一个移动端上下滑动的轮播组件

效果 

在这里插入图片描述

 

<!-- 上下滑动轮播图片查看 -->
<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>

猜你喜欢

转载自blog.csdn.net/yuan_jlj/article/details/111314323