Vue 的业务中前端本地列表超过N条开始轮播(手动轮播/自动轮播)

168 阅读1分钟

Vue 的业务中前端本地列表超过N条开始轮播

业务场景 :

列表超过几条要轮播(手动轮播/自动轮播) QQ截图20231117144335.png

1. JavaScript 部分

export default {
 data() {
    return {
      detailDatas: {
        collegeName: "",
      },
      currentX: 0,
    };
  },
 methods: {
// 向左轮播按钮
swiperToLef() {
      if (this.currentX === 0) return;
      const itemWidth = this.$refs.swiperGroup.children[0].offsetWidth;

![QQ截图20231117144335.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f5159af9ff2e4abf9d58f8eb573de1b6~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1733&h=470&s=401402&e=png&b=fdfbfb)
      this.currentX += itemWidth + 20;
    },
// 向右轮播按钮
swiperToRig() {
      if (this.detailDatas.expertList?.length <= 3) return;
      const itemWidth = this.$refs.swiperGroup.children[0].offsetWidth;
      const currentX = this.currentX - (itemWidth + 20);
      if (Math.abs(currentX) > this.$refs.swiperGroup.offsetWidth) return;
      this.currentX -= itemWidth + 20;
    },
 }
}

2.HTML部分

 <section>
        <h5 class="section-tit">专家团队</h5>
        <div
          class="swiper-section"
          v-if="detailDatas.expertList && detailDatas.expertList.length > 0"
        >
          <div class="swiper-btn btn-lef" @click="swiperToLef">
            <img src="@/assets/images/swiper_btn_lef.png" draggable="false" />
          </div>
          <div class="swiper-btn btn-rig" @click="swiperToRig">
            <img src="@/assets/images/swiper_btn_rig.png" draggable="false" />
          </div>
          <div class="swiper-group-con">
            <ul
              class="swiper-group"
              ref="swiperGroup"
              :style="{ transform: `translateX(${currentX}px)` }"
            >
              <li v-for="(item, index) in detailDatas.expertList" :key="index">
                <el-image
                  v-if="item.imgPath && item.imgPath.indexOf('http') === 0"
                  fit="contain"
                  class="swiper-bg"
                  :src="item.imgPath"
                />
                <el-image
                  v-else
                  class="swiper-bg"
                  :src="require('@/assets/images/index-banner.png')"
                />

                <div class="swiper-name">
                  <div class="name">{{ item.name }}</div>
                  <div class="t-lines-2">{{ item.teamDesc }}</div>
                </div>
                <div class="swiper-context">
                  <div class="swiper-name-con">{{ item.name }}</div>
                  <div class="swiper-section">
                    <b>研究方向:</b>
                    <p class="t-lines-2">{{ item.direction }}</p>
                  </div>
                  <div class="swiper-section">
                    <b>团队简介:</b>
                    <p class="t-lines-5">{{ item.teamDesc }}</p>
                  </div>
                </div>
              </li>
            </ul>
          </div>
        </div>
      <div class="notData" v-else>
         <p>当前暂无相关信息</p>
      </div>
  </section>

3. Css部分 (scss)

.swiper-section {
  position: relative;
  $btnImgWidth: 40px;
  $btnHorizontalOffset: -($btnImgWidth + 10px);

  .swiper-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 24px;
    cursor: pointer;
    z-index: 1;

    & > img {
      width: $btnImgWidth;
      height: $btnImgWidth;
    }
  }

  .btn-lef {
    left: $btnHorizontalOffset;
  }

  .btn-rig {
    right: $btnHorizontalOffset;
  }
}

.swiper-group-con {
  position: relative;
  overflow: hidden;
}

.swiper-group {
  $liMargin: 10px;
  $liWidth: 1200px / 3 - $liMargin * 2;
  white-space: nowrap;
  list-style: none;
  margin: 0;
  padding: 0;
  will-change: transform;
  transform: translateX(0);
  transition: transform 400ms ease;

  & > li {
    position: relative;
    display: inline-block;
    width: $liWidth;
    height: 217px;
    margin: 0 $liMargin;
    overflow: hidden;

    &:hover .swiper-context {
      z-index: 10 !important;
      opacity: 1 !important;
    }

    &:hover .swiper-name {
      transform: translateY(100px) !important;
    }

    .swiper-bg {
      width: inherit;
      height: inherit;
    }

    .swiper-name-con {
      color: #fff;
      font-size: 14px;
      padding: 12px 18px;
    }

    .swiper-name {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.45);
      transform: translateY(0);
      transition: transform 400ms ease-in-out;
      z-index: 1;
      // opacity: 0;
      @extend .swiper-name-con;

      .name {
        margin-bottom: 10px;
      }
    }

    .swiper-context {
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.45);
      opacity: 0;
      transition: opacity 200ms ease;
      z-index: -1;

      .swiper-name-con {
        font-size: 18px !important;
        font-weight: 700 !important;
        margin-bottom: 10px;
      }
    }

    .swiper-section {
      display: flex;
      align-items: flex-start;
      overflow: hidden;
      color: #fff;
      padding: 0 18px;
      font-size: 14px;

      & + .swiper-section {
        margin-top: 30px;
      }

      & > p {
        flex: 1;
        margin: 0;
      }
    }
  }
}