Vue3封装一个轮播图组件

2023-12-15 16:42:54

先看效果
在这里插入图片描述

编写组件代码 CarouselChart.vue

<template>
  <div class='img-box'>
    <el-button @click='previousImages' v-if='props.showBtn'></el-button>
    <div class='img'>
      <div style='display: flex;gap: 20px' id='move'>
        <img
          class='img-item' v-for='(item) in props.imgList'
          :key='item.src'
          :src='item.src'
          alt='' />
      </div>
    </div>
    <el-button @click='nextImages' v-if='props.showBtn'></el-button>

    <div class='spots' v-if='props.showSpot'>
      <div
        class='spot'
        v-for='(item,index) in props.imgList.length / 2'
        :key='index'
        :class="{
          'active':index*2 === currentIndex
        }"
        @click='setCurIndex(index)'
      >
      </div>
    </div>
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue'

const emit = defineEmits(['handlePrev', 'handleNext'])
const props = defineProps({
  // 图片
  imgList: {
    type: Object,
    required: true,
  },
  // 是否显示左右切换按钮
  showBtn: {
    type: Boolean,
    default: true,
  },
  // 是否显示小圆点
  showSpot: {
    type: Boolean,
    default: true,
  },
})

const currentIndex = ref(0)

const updateVisibleImages = () => {
  const imgDom = document.querySelector('#move')
  imgDom.style.transform = `translateX(-${((currentIndex.value * 440) + ((currentIndex.value) * 20))}px)`
  imgDom.style.transition = `all 0.5s`
}


const nextImages = () => {
  if (currentIndex.value + 2 >= props.imgList.length) return
  currentIndex.value += 2
  updateVisibleImages()
  emit('handleNext')
}

const previousImages = () => {
  if (currentIndex.value <= 0) return
  currentIndex.value -= 2
  updateVisibleImages()
  emit('handlePrev')
}

const setCurIndex = (index) => {
  currentIndex.value = index * 2
  updateVisibleImages()
}

</script>

<style scoped lang='scss'>
.img-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  width: 100%;
  height: 100%;
  position: relative;

  .img {
    width: 900px;
    overflow: hidden;
    transition: all 0.5s;

    .img-item {
      width: 440px;

      img {
        width: 100%;
      }
    }
  }

  .spots {
    position: absolute;
    left: 50%;
    margin-top: 20%;
    transform: translateX(-50%);
    display: flex;
    gap: 20px;
    align-items: center;
    justify-content: center;


    .spot {
      width: 10px;
      height: 10px;
      border-radius: 5px;
      background-color: #1a60ea;
      transition: all 0.5s;
      cursor: pointer;

      &:hover {
        transform: scale(1.5);
      }
    }

    .active {
      background-color: #ea1ccc;
      transform: scale(2);
      transition: all 0.5s;
    }
  }
}
</style>

使用这个组件

<template>
  <div class='h-full w-full flex align-center justify-center'>
    <CarouselChart
      :img-list='imgList'
      @handlePrev='handlePrev'
      @handleNext='handleNext'
    />
  </div>
</template>
<script setup>
import { reactive } from 'vue'
import { ElMessage } from 'element-plus'
import img1 from '@/assets/lunbo/01.jpg'
import img2 from '@/assets/lunbo/02.jpg'
import img3 from '@/assets/lunbo/03.jpg'
import img4 from '@/assets/lunbo/04.jpg'
import img5 from '@/assets/lunbo/05.jpg'
import img6 from '@/assets/lunbo/06.jpg'
import img7 from '@/assets/lunbo/07.jpg'
import img8 from '@/assets/lunbo/08.jpg'
import img9 from '@/assets/lunbo/09.jpg'
import img10 from '@/assets/lunbo/10.jpg'

let imgList = reactive([
  { src: img1 },
  { src: img2 },
  { src: img3 },
  { src: img4 },
  { src: img5 },
  { src: img6 },
  { src: img7 },
  { src: img8 },
  { src: img9 },
  { src: img10 },
])

function handleNext() {
  ElMessage.warning('下一张')
}

function handlePrev() {
  ElMessage.success('上一张')
}

</script>

文章来源:https://blog.csdn.net/SongZhengxing_/article/details/134937905
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。