Vue3 如何实现类似 Fortnite.gg 商店的图片自动切换效果?

Vue3 如何实现类似 Fortnite.gg 商店的图片自动切换效果?
最新回答
你若安好那还得了

2023-02-20 01:22:05

在 Vue3 中实现类似 Fortnite.gg 商店的图片自动切换效果,核心思路是通过 动态绑定图片数组 + CSS 过渡动画第三方动画库 实现轮播。针对不同项目图片数量不同的问题,可采用以下方案:

方案 1:基于 CSS 动画 + 动态类名(推荐)

通过 v-for 循环图片数组,结合 @keyframes 动画实现自动切换,无需额外依赖。

实现步骤
  1. 修改数据结构确保每个商品对象包含图片数组(如 item.images),例如:

    const shopList = ref([ { name: "商品A", price: 100, images: ["img1.jpg", "img2.jpg", "img3.jpg"] // 动态图片数组 }, // 其他商品...]);
  2. 动态绑定图片并添加动画使用 v-for 循环图片,通过 transition-group 或 CSS @keyframes 实现切换效果:

    <div class="shop-section" v-for="(items, index) in shopStore.shopList" :key="index"> <h2 class="section-name">{{ index }}</h2> <div :class="'shop-card ' + index" v-for="item in items" :style="{ height: index.includes('Jam Tracks') ? '200px' : 'auto' }" @click="preview(item)" > <!-- 图片轮播容器 --> <div class="image-carousel" :style="{ height: index.includes('Jam Tracks') ? '200px' : 'auto' }"> <img v-for="(img, imgIndex) in item.images" :key="imgIndex" :src="img" :alt="item.name" class="carousel-img" :class="{ 'active': currentImgIndex[item.id] === imgIndex }" /> </div> <div class="item-info-container"> <p class="item-name">{{ item.name }}</p> <p class="item-price"> <img style="width: 20px; vertical-align: middle;" src="@/assets/imgs/vbuck.png" alt=""> {{ item.price }} </p> </div> </div></div>
  3. 添加 CSS 动画通过 @keyframes 实现淡入淡出或滑动效果:

    .image-carousel { position: relative; overflow: hidden;}.carousel-img { position: absolute; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s ease;}.carousel-img.active { opacity: 1;}/* 或滑动效果 */@keyframes slide { 0% { transform: translateX(0); } 25% { transform: translateX(-100%); } 50% { transform: translateX(-100%); } 75% { transform: translateX(-200%); } 100% { transform: translateX(0); }}.slide-animation { display: flex; animation: slide 10s infinite;}
  4. 通过 JavaScript 控制切换逻辑使用 setInterval 动态更新当前显示的图片索引:

    import { ref, onMounted, onBeforeUnmount } from "vue';const currentImgIndex = ref({}); // 存储每个商品的当前图片索引onMounted(() => { shopStore.shopList.forEach(itemGroup => { itemGroup.forEach(item => { currentImgIndex.value[item.id] = 0; // 初始化索引 startAutoSwitch(item.id, item.images.length); }); });});function startAutoSwitch(itemId, imgCount) { let timer = setInterval(() => { currentImgIndex.value[itemId] = (currentImgIndex.value[itemId] + 1) % imgCount; }, 3000); // 每3秒切换一次 // 组件卸载时清除定时器 onBeforeUnmount(() => clearInterval(timer));}
方案 2:使用第三方轮播库(如 Swiper.js)

若需更复杂的交互(如手势滑动、分页器),可集成

Swiper.js

实现步骤
  1. 安装 Swiper

    npm install swiper
  2. 在组件中使用

    <template> <div class="shop-section" v-for="(items, index) in shopStore.shopList" :key="index"> <h2 class="section-name">{{ index }}</h2> <div :class="'shop-card ' + index" v-for="item in items" :style="{ height: index.includes('Jam Tracks') ? '200px' : 'auto' }" @click="preview(item)" > <!-- Swiper 容器 --> <swiper :modules="[Autoplay]" :autoplay="{ delay: 3000 }" :loop="true" :style="{ height: index.includes('Jam Tracks') ? '200px' : 'auto' }" > <swiper-slide v-for="(img, imgIndex) in item.images" :key="imgIndex"> <img :src="img" :alt="item.name" class="item-img" /> </swiper-slide> </swiper> <div class="item-info-container"> <p class="item-name">{{ item.name }}</p> <p class="item-price"> <img style="width: 20px; vertical-align: middle;" src="@/assets/imgs/vbuck.png" alt=""> {{ item.price }} </p> </div> </div> </div></template><script setup>import { Swiper, SwiperSlide } from "swiper/vue';import { Autoplay } from 'swiper/modules';import 'swiper/css';</script>
关键点总结
  • 动态图片处理:通过 v-for 循环 item.images 数组,支持不同商品不同图片数量。
  • 自动切换逻辑

    纯 CSS:通过 @keyframes 或 transition + 动态类名。

    JavaScript:使用 setInterval 更新索引。

    第三方库:如 Swiper 提供开箱即用的轮播功能。

  • 性能优化:对大量图片使用懒加载(如 v-lazy)或虚拟滚动。
最终推荐方案
  • 简单需求:使用 方案 1(CSS + JavaScript),轻量且可控。
  • 复杂交互:选择 方案 2(Swiper.js),支持手势、分页器等高级功能。

(Swiper.js 示例效果,可自定义样式匹配 Fortnite.gg 风格)