先看效果
编写组件代码 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'><imgclass='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'><divclass='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) returncurrentIndex.value += 2updateVisibleImages()emit('handleNext')
}const previousImages = () => {if (currentIndex.value <= 0) returncurrentIndex.value -= 2updateVisibleImages()emit('handlePrev')
}const setCurIndex = (index) => {currentIndex.value = index * 2updateVisibleImages()
}</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>