vue3实现类似于商城商品详情效果图多图展示滑动效果

 主要使用css的transform属性进行左右滑动,代码如下

<script setup lang="ts">

const props = defineProps({
  images: []
})

const data = ref({

  imgUrlList:[], //图片数据
  imgActiveIndex: 0, // 当前移动图片的索引值

  imgDistance: 0, // 每次移动的距离

  firstIndex: 0,//一组图片的第一张索引
  lastIndex: 3 //一组图片的最后一张索引

});

if (props.images) {
  //将传进来的数据赋值给定义的数据
  data.value.imgUrlList = props.images;
}

const imgStyle = computed(() => {
  return {
    transform: `translate3d(${data.value.imgDistance}px, 0, 0)` // 计算移动的距离(x,y,z)
  }
})

function changeImg(item, index) {
  data.value.imgActiveIndex = index
}

function goToSlide(currentIndex){

  //向右移动
  if(currentIndex > data.value.imgActiveIndex){

    if(currentIndex >= data.value.firstIndex && currentIndex <= data.value.lastIndex){
      //当前索引在区间内,不做操作

    }else{

      let oldLastIndex = data.value.lastIndex;

      //设置区间
      data.value.firstIndex = currentIndex - 3;
      data.value.lastIndex = currentIndex;


      //移动步数
      let rightSetp = data.value.lastIndex - oldLastIndex;

      //向后移动
      let index = 0
      const temp = window.setInterval(() => {
        if (index < (48 * rightSetp)) {
          data.value.imgDistance -= 2 // 每次向右移动的距离
          index++
          return
        } else {
          window.clearInterval(temp)
        }
      }, 0);
    }
  }

  //向左移动
  if(currentIndex < data.value.imgActiveIndex){
    if(currentIndex >= data.value.firstIndex && currentIndex <= data.value.lastIndex){
      //当前索引在区间内,不做操作
    }else{

      let oldLastIndex = data.value.lastIndex;

      //设置区间
      data.value.firstIndex = currentIndex;
      data.value.lastIndex = currentIndex + 3;

      //移动步数
      let leftSetp = oldLastIndex - data.value.lastIndex;

      //向前移动
      let index = 0
      const temp = window.setInterval(() => {
        if (index < (48 * leftSetp)) {
          data.value.imgDistance += 2 // 每次向右移动的距离
          index++
          return
        } else {
          window.clearInterval(temp)
        }
      }, 0);
    }

  }

  //设置当前索引
  data.value.imgActiveIndex = currentIndex
}

function imgLeft() {
  //当前索引减1
  data.value.imgActiveIndex--
  if(data.value.imgActiveIndex >= data.value.firstIndex && data.value.imgActiveIndex <= data.value.lastIndex){
    //当前索引在区间内,不做操作
  }else{
    //判断当前索引是否小于最小值
    if(data.value.imgActiveIndex >= 0){

      //更新区间范围
      data.value.firstIndex --;
      data.value.lastIndex --;

      //向前移动
      let index = 0
      const temp = window.setInterval(() => {
        if (index < 48) {
          data.value.imgDistance += 2 // 每次向右移动的距离
          index++
          return
        } else {
          window.clearInterval(temp)
        }
      }, 0);

    }
  }
}

function imgRight() {
  //当前索引加1
  data.value.imgActiveIndex ++

  if(data.value.imgActiveIndex >= data.value.firstIndex && data.value.imgActiveIndex <= data.value.lastIndex){
    //当前索引在区间内,不做操作
  }else{
    //判断当前索引是否超出最大值
    if(data.value.imgActiveIndex <= data.value.imgUrlList.length - 1){

      //更新区间范围
      data.value.firstIndex ++;
      data.value.lastIndex ++;

      //向后移动
      let index = 0
      const temp = window.setInterval(() => {
        if (index < 48) {
          data.value.imgDistance -= 2 // 每次向右移动的距离
          index++
          return
        } else {
          window.clearInterval(temp)
        }
      }, 0);

    }else if(data.value.imgActiveIndex > data.value.imgUrlList.length - 1){
      //最后一张

      //设置当前索引
      data.value.imgActiveIndex = 0;

      //更新区间范围
      data.value.firstIndex = 0;
      data.value.lastIndex = 3;

      //移动到最开始
      let index = 0
      const temp = window.setInterval(() => { // 利用定时器实现图片左右移动的动画效果
        if (index < Math.abs((((data.value.imgUrlList.length -1) - 3) * -96)/2)) { // 取绝对值再除
          data.value.imgDistance += 2 // 每次向左移动的距离 (移动总距离为48*this.imgDistance)
          index++
          return
        } else {
          window.clearInterval(temp) // 移动完清除定时器
        }
      }, 0)
    }
  }
}


</script>

<template>

  <div class="img_carousel_container">

    <!--大图-->
    <div class="main_container">
      <img :src="data.imgUrlList[data.imgActiveIndex]">

      <!-- 小圆点 -->
      <div class="carousel-dots">
        <span v-for="(dot, index) in images.length" :key="index" :class="{ 'active-dot': data.imgActiveIndex === index }" @click="goToSlide(index)"></span>
      </div>

    </div>

    <div class="thumb_container">
      <!--左箭头-->
      <VIcon
        v-if="data.imgActiveIndex != 0"
        size="30"
        icon="tabler-chevron-left"
        @click="imgLeft()"
      />
      <div v-else style="width: 30px"></div>

      <!--缩略图-->
      <div class="img_carousel_thumb">
        <div class="thumb_img" v-for="(item,index) in data.imgUrlList" :key="index" :style="imgStyle" @click="changeImg(item, index)">
          <img :class="index === data.imgActiveIndex ? 'img_active' : 'img_unactive'" :src="item">
        </div>
      </div>

      <!--右箭头-->
      <VIcon
        v-if="data.imgUrlList.length > 4"
        size="30"
        icon="tabler-chevron-right"
        @click="imgRight()"
      />
        <div v-else style="width: 30px"></div>
    </div>

  </div>

</template>

<style lang="scss" scoped>
.carousel-dots {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
}
.carousel-dots span {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #ccc;
  margin: 0 5px;
  cursor: pointer;
}
.carousel-dots .active-dot {
  background-color: #333;
}
/*容器*/
.img_carousel_container{
  width: 444px;
  height: 350px;
  display: flex;
  flex-direction: column;
  align-items: center;

  /*大图*/
  .main_container {
    width: 386px;
    height: 270px;
    position: relative;

    img{
      max-width: 100%; /* 图片最大宽度为容器宽度 */
      max-height: 100%; /* 图片最大高度为容器高度 */
      position: absolute; /* 绝对定位 */
      top: 0; /* 顶部对齐 */
      left: 0; /* 左边对齐 */
      right: 0; /* 右边对齐 */
      bottom: 0; /* 底部对齐 */
      margin: auto; /* 自动外边距,居中显示 */
    }
  }


  /*缩略图*/
  .thumb_container{
    width: 444px;
    height: 75px;
    margin-top: 5px;
    display: flex;
    flex-direction: row;
    align-items: center;
    overflow: hidden;

    .img_carousel_thumb{
      width: 386px;
      display: flex;
      flex-direction: row;
      align-items: center;
      overflow: hidden;

      .thumb_img{
        flex-shrink: 0;
        width: 96px;
        height: 75px;

        img{
          max-width: 100%; /* 图片最大宽度为容器宽度 */
          max-height: 100%; /* 图片最大高度为容器高度 */
          position: absolute; /* 绝对定位 */
          top: 0; /* 顶部对齐 */
          left: 0; /* 左边对齐 */
          right: 0; /* 右边对齐 */
          bottom: 0; /* 底部对齐 */
          margin: auto; /* 自动外边距,居中显示 */
        }
      }
    }
  }

}

/*图片选中*/
.img_active{
  opacity: 1;
}
/*图片未选中*/
.img_unactive{
  opacity: 0.4;
}


</style>

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中,你可以使用组件的方式实现轮播效果。下面是一个简单的例子: 1. 创建Carousel.vue组件 ```html <template> <div class="carousel"> <div class="carousel-inner"> <slot></slot> </div> <div class="carousel-controls"> <button @click="prevSlide">Prev</button> <button @click="nextSlide">Next</button> </div> </div> </template> <script> export default { data() { return { currentSlide: 0, totalSlides: 0 }; }, mounted() { this.totalSlides = this.$slots.default.length; }, methods: { prevSlide() { this.currentSlide = (this.currentSlide - 1 + this.totalSlides) % this.totalSlides; }, nextSlide() { this.currentSlide = (this.currentSlide + 1) % this.totalSlides; } } }; </script> <style> .carousel { position: relative; overflow: hidden; height: 300px; } .carousel-inner { display: flex; transition: transform 0.5s ease-out; transform: translateX(-${props.currentSlide * 100}%); } .carousel-controls { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); } .carousel-controls button { margin-right: 10px; } </style> ``` 在上面的代码中,我们定义了一个Carousel组件,它包含一个插槽(用于插入轮播片)和两个按钮(用于控制轮播滑动)。我们使用了flex布局和transform属性来实现轮播滑动效果。 2. 在父组件中使用Carousel组件 ```html <template> <div class="app"> <carousel> <img src="./img/slide1.jpg"> <img src="./img/slide2.jpg"> <img src="./img/slide3.jpg"> </carousel> </div> </template> <script> import Carousel from './Carousel.vue'; export default { components: { Carousel } }; </script> <style> .app { max-width: 800px; margin: 0 auto; } </style> ``` 在上面的代码中,我们在父组件中使用了Carousel组件,并在插槽中插入了三张片。这样就完成了一个简单的轮播效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值