<template> <section class="swiper-container" @mouseenter="stopAutoPlay" @mouseleave="startAutoPlay"> <div><span style="font-size: 36px!important;">推荐</span></div> <div class="carousel"> <div class="carousel-inner" :style="{ transform: `translateX(-${currentIndex * 100}%)` }"> <div class="carousel-item" v-for="(page, pageIndex) in pages" :key="pageIndex"> <div class="carousel-item-content" v-for="(item, itemIndex) in page" :key="itemIndex"> <div style="width: 222px;height: 222px;background-color: antiquewhite;"> <img :src="item.image" :alt="item.title" /> </div> <h3>{{ item.title }}</h3> <p>{{ item.description }}</p> </div> </div> </div> </div> <button v-show="displayBtn" class="carousel-control prev" @click="prevPage" style="font-size: 24px;">‹</button> <button v-show="displayBtn" class="carousel-control next" @click="nextPage">›</button> <div class="carousel-dots"> <span v-for="(page, pageIndex) in pages" :key="pageIndex" :class="{ active: pageIndex === currentIndex }" @click="goToPage(pageIndex)"></span> </div> </section> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue'; const displayBtn = ref(true); const pages = ref([ [ { image: 'image1.jpg', title: 'Title 1', description: 'Description 1' }, { image: 'image2.jpg', title: 'Title 2', description: 'Description 2' }, { image: 'image3.jpg', title: 'Title 3', description: 'Description 3' }, { image: 'image4.jpg', title: 'Title 4', description: 'Description 4' }, { image: 'image5.jpg', title: 'Title 5', description: 'Description 5' }, ], [ { image: 'image1.jpg', title: 'Title 1', description: 'Description 1' }, { image: 'image2.jpg', title: 'Title 2', description: 'Description 2' }, { image: 'image3.jpg', title: 'Title 3', description: 'Description 3' }, { image: 'image4.jpg', title: 'Title 4', description: 'Description 4' }, { image: 'image5.jpg', title: 'Title 5', description: 'Description 5' }, ], // ... 其他页面数据 ]); const currentIndex = ref(0); let autoPlayInterval = null; const nextPage = () => { currentIndex.value = (currentIndex.value + 1) % pages.value.length; }; const prevPage = () => { currentIndex.value = (currentIndex.value - 1 + pages.value.length) % pages.value.length; }; const goToPage = (index) => { currentIndex.value = index; }; const startAutoPlay = () => { autoPlayInterval = setInterval(nextPage, 7000); displayBtn.value = false; }; const stopAutoPlay = () => { clearInterval(autoPlayInterval); displayBtn.value = true; }; onMounted(() => { startAutoPlay(); }); onUnmounted(() => { stopAutoPlay(); }); </script> <style scoped> .swiper-container { position: relative; width: 100%; height: 400px; background-color: rgb(119, 194, 255); } .carousel { user-select: none; background-color: black; position: relative; width: 1200px; overflow: hidden; margin: 0 auto; } .carousel-inner { display: flex; transition: transform 0.5s ease; } .carousel-item { display: flex; justify-content: center; align-items: center; flex: 1 0 100%; gap: 1rem; } .carousel-item-content { /* width: 80%; */ /* flex: 1; */ text-align: start; background-color: aqua; } .carousel-item-content img { width: 150px; height: 150px; } .carousel-control { position: absolute; top: 50%; transform: translateY(-50%); background: rgba(255, 255, 255, 1); color: black; border: none; padding: 20px; cursor: pointer; } .carousel-control.prev { left: 10px; } .carousel-control.next { right: 10px; } .carousel-dots { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); display: flex; gap: 2rem; } .carousel-dots span { width: 8px; height: 8px; background: gray; border-radius: 50%; cursor: pointer; } .carousel-dots span.active { background: white; } </style>