vue3 大屏列表轮播,使用transition-group
一、transition-group介绍
transition-group 是 Vue 框架中专门用来给列表添加动画效果的内置组件,它能让你在做添加、删除或排序列表项时,看到平滑的过渡动画 。
对应的css:
例如:transition-group的类名为 list
动画类名就为:
list-enter-active、list-leave-active 控制动画过程,list-enter-from、list-leave-to 控制开始结束状态
二、代码实现
<template> <div @mouseenter="pauseCarousel" @mouseleave="resumeCarousel"> <transition-group class="contentBox" name="carousel" tag="div"> <div v-for="item in rows" :key="item.id"> <div class="content"> <el-image class="img" :src="item.shop_logo || slaughterDefault" /> <div class="info"> <el-text class="text" line-clamp="2">{{ item.name }}</el-text> <div class="detail"> <span class="count">累计屠宰:{{ item.total_quantity }}头</span> <div class="rating"> <span>好评率:</span> <el-rate v-model="item.positiveRating" size="small" disabled-void-color="#272C1B" disabled /> <span class="ratingNum">{{ item.good_rate }}%</span> </div> </div> </div> </div> </div> </transition-group> </template> <script lang="ts" setup> import { onMounted, onBeforeUnmount, ref, watch } from 'vue' // 数据 const data: any = ref([]) // 轮播 const rows = ref([]); const currentIndex = ref(3); // 从第4个开始(索引3) const isAnimating = ref(false); const isPaused = ref(false); // 暂停状态 const timer = ref(null); // 定时器 onMounted(async() => { // 获取数据 await getData() }) onBeforeUnmount(() => { clearInterval(timer.value) }) const getData = async() => { try { // 自己的接口获取数据 // 显示几条就截取几条 rows.value = data.value.slice(0, 3) if (data.value.length > 0) { startCarousel() } } catch (error) { console.error("获取数据失败:", error); data.value = [] } } // 轮播动画 const startAnimation = () => { if (isAnimating.value || isPaused.value) return; isAnimating.value = true; // 移除第一条数据(会触发动画) rows.value.shift(); // 添加下一条数据(循环整个列表) const nextItem = data.value[currentIndex.value % data.value.length]; rows.value.push(nextItem); currentIndex.value++; // 重置索引到0如果已经到达列表末尾 if (currentIndex.value >= data.value.length) { currentIndex.value = 0; } // 等待动画完成后重置状态 setTimeout(() => { isAnimating.value = false; }, 400); }; // 开始轮播 const startCarousel = () => { clearInterval(timer.value); // 先清除已有定时器 if (data.value.length > 3) { timer.value = setInterval(startAnimation, 3000); } }; // 暂停轮播 const pauseCarousel = () => { isPaused.value = true; clearInterval(timer.value); }; // 继续轮播 const resumeCarousel = () => { isPaused.value = false; startCarousel(); // 重新开始轮播 }; </script> <style lang="scss" scoped> /* 轮播过渡动画 - 边轮播边过渡 */ .carousel-enter-active { transition: all 0.5s ease-out; z-index: 10; } .carousel-leave-active { transition: all 0.5s ease-in; position: absolute; width: 100%; left: 0; right: 0; } .carousel-enter-from { opacity: 0; transform: translateY(100%); } .carousel-leave-to { opacity: 0; transform: translateY(-100%); } .carousel-move { transition: transform 0.5s ease; } </style>