vue无缝循环轮播

在网上看了几个无缝循环轮播的实现方法,使用方法都比较复杂,所以这里提供一种比较简单的实现方式

gitee: https://gitee.com/philippines-kisses-snow/rotation

结构和理论梳理

理论

image
轮播的原理就是通过translateY/translateX移动轮播容器+过渡达到轮播项上下左右轮播效果的,为了达到无缝循环效果,这里在轮播容器的末尾追加第一项内容,如图:【“1”,“2”,“3”,“4”】这四项是我想轮播的内容,此时在容器末尾还追加了“1”,当轮播到“4”时,“4”与“1”之间的切换就达到了无缝效果,在切换到末尾的“1”时,等待过渡结束后取消过渡,立即切换到开头的“1”,这样就达到了将末尾切换到开始的循环

结构

  <div>
    <div>
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>1</div>
    </div>
  </div>

上下轮播代码

image

<template>
  <div style="height: 200px;overflow: hidden;">
    <div class="box" :style="{ transitionDuration: `${transitionDuration}ms`, transform: `translateY( ${translateX}px)`}">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>1</div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from 'vue';
// 当前滚动高度
const translateX = ref(0)
// 过渡时间
const transitionDuration = ref(500)

// 每次滚动高度
const translateValue = 200
// 滚动项个数
const switeCount = 4

onMounted(() => {
  setInterval(() => {
    translateX.value -= translateValue
    transitionDuration.value = 500
    if(translateX.value === -translateValue * switeCount) {
      setTimeout(() => {
        translateX.value -= translateValue
        transitionDuration.value = 0
        translateX.value = 0
      }, 600)
    }
  }, 2000)
})

</script>

<style scoped>

.box div {
  width: 300px;
  height: 200px;
  background-color: aquamarine;
}
</style>

基于这个理论的轮播表格

image

<template>
  <div style="width: 800px;" class="table">
    <table style="width: 100%;" border="0" cellpadding="0" cellspacing="0">
      <thead style="background-color: #333F4F;">
        <tr :style="{ height: rowHeight + 'px'}">
          <th style="max-width: 60px;width: 60px;">NO.</th>
          <th style="max-width: 120px;width: 120px;">客户代码</th>
          <th style="max-width: 120px;width: 120px;">客户名称</th>
          <th style="max-width: 120px;width: 120px;">提货人</th>
          <th style="max-width: 120px;width: 120px;">车牌</th>
          <th style="max-width: 120px;width: 120px;">出货日</th>
          <th>目的地</th>
        </tr>
      </thead>
    </table>
    <div style="overflow: hidden;position: relative;top: -2px;" :style="{ height: (Math.min(maxRow, tableData.length) * rowHeight) + 'px' }">
      <table  border="0" cellpadding="0" cellspacing="0" style="width: 100%;" :style="{ transitionDuration: `${transitionDuration}ms`, transform: `translateY( ${translateX}px)`}">
        <tbody style="background-color: #333F4F;">
          <tr v-for="(item, index) in tableData" :key="index" :style="{ height: rowHeight + 'px'}">
            <td style="max-width: 60px;width: 60px;text-align: center;">{{ item.demo1 }}</td>
            <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo2 }}</td>
            <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo3 }}</td>
            <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo4 }}</td>
            <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo5 }}</td>
            <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo6 }}</td>
            <td style="text-align: center;">{{ item.demo7 }}</td>
          </tr>
          <template v-for="(item, index) in tableData" :key="index">
            <tr v-if="index < maxRow && tableData.length > maxRow" :style="{ height: rowHeight + 'px' }">
              <td style="max-width: 60px;width: 60px;text-align: center;">{{ item.demo1 }}</td>
              <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo2 }}</td>
              <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo3 }}</td>
              <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo4 }}</td>
              <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo5 }}</td>
              <td style="text-align: center;max-width: 120px;width: 120px;">{{ item.demo6 }}</td>
              <td style="text-align: center;">{{ item.demo7 }}</td>
            </tr>
          </template>
        </tbody>
      </table>
    </div>
  </div>  
</template>

<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { tableData } from './table';

const translateX = ref(0)
const transitionDuration = ref(500)

const maxRow = 8
const rowHeight = 48
const translateValue = rowHeight
const switeCount = tableData.length

onMounted(() => {
  setInterval(() => {
    if(tableData.length > maxRow) {
      translateX.value -= translateValue
      transitionDuration.value = 500
      if(translateX.value === -translateValue * switeCount) {
        setTimeout(() => {
          translateX.value -= translateValue
          transitionDuration.value = 0
          translateX.value = 0
        }, 600)
      }
    }
  }, 2000)
})

</script>

<style scoped>

.box div {
  width: 300px;
  height: 200px;
  background-color: aquamarine;
}

table {
  color: #fff;
}

.table {
  border: 1px solid #046DB8;
  margin: auto;
}

table {
  color: #fff;
}
td {
  border-top: 1px solid #046DB8;
  border-bottom: 1px solid #046DB8;
  border-left: 1px solid #046DB8;
}

th {
  border-left: 1px solid #046DB8;
}

tr th:nth-child(1) {
  border-left: 0 !important;
}


tr td:nth-child(1) {
  border-left: 0 !important;
}
</style>

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue 2 中实现无缝轮播可以通过以下步骤进行: 1. 创建一个 Vue 组件,命名为`Carousel`。 2. 在`Carousel`组件中,定义一个数组来存储需要轮播的图片列表。 3. 在`mounted`生命周期钩子函数中,初始化轮播的一些参数,例如当前显示的图片索引、定时器等。 4. 在模板中,使用`v-for`指令循环渲染图片列表,并设置每个图片项的样式,使其水平排列。 5. 使用`transform: translateX()`样式属性,对轮播项进行水平移动,实现轮播效果。可以通过计算当前索引和图片宽度来设置移动的距离。 6. 添加一个定时器,在一定时间间隔内更新当前显示的图片索引,实现自动轮播效果。 7. 监听鼠标滑入和滑出事件,在鼠标滑入时清除定时器,在鼠标滑出时重新启动定时器,实现鼠标悬停时暂停轮播的效果。 以下是一个简单示例代码: ```html <template> <div class="carousel"> <div class="carousel-wrapper" :style="{ transform: `translateX(${translateX}px)` }"> <div v-for="(item, index) in images" :key="index" class="carousel-item"> <img :src="item" alt="carousel item" /> </div> </div> </div> </template> <script> export default { data() { return { images: [ 'image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg', ], currentIndex: 0, translateX: 0, intervalId: null, }; }, mounted() { this.startCarousel(); }, beforeDestroy() { clearInterval(this.intervalId); }, methods: { startCarousel() { this.intervalId = setInterval(() => { this.nextSlide(); }, 3000); }, nextSlide() { if (this.currentIndex === this.images.length - 1) { this.currentIndex = 0; this.translateX = 0; } else { this.currentIndex++; this.translateX -= this.$refs.carouselItem.offsetWidth; } }, }, }; </script> <style> .carousel { width: 100%; overflow: hidden; } .carousel-wrapper { display: flex; transition: transform 0.5s; } .carousel-item { flex-shrink: 0; } </style> ``` 以上代码是一个简单的示例,实现了简单的无缝轮播效果。你可以根据需求进行进一步的样式和功能定制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值