feat(components): 优化数字滚动效果并添加循环播放控制

- 在 CountTo 组件中添加 update:readyLoop 事件,用于通知数字滚动完成
- 在 Header 组件中使用 readyLoop 事件来控制 Swiper 轮播的初始化和销毁
- 优化了数字滚动的动画效果,确保滚动到目标数字后停止
This commit is contained in:
du.meimei
2025-05-28 17:22:20 +08:00
parent 70b3dc3592
commit 016d4ac4fc
2 changed files with 32 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
<template>
<span class="count-to">{{ formattedCount }}</span>
<span class="count-to">{{ formattedCount }} </span>
</template>
<script setup>
@@ -20,6 +20,7 @@ const props = defineProps({
},
})
const emit = defineEmits(['update:readyLoop'])
// 工具函数:将 "1,000" 转成 1000
const parseValue = (val) => {
if (typeof val === 'number') return val
@@ -42,6 +43,9 @@ const formattedCount = ref('0')
const animateCount = () => {
parsedEnd.value = parseValue(props.end)
formattedCount.value = props.end
let start = 0
const totalSteps = Math.round(props.duration / 16)
const increment = parsedEnd.value / totalSteps
@@ -50,7 +54,8 @@ const animateCount = () => {
start += increment
if (start >= parsedEnd.value) {
currentCount.value = parsedEnd.value
formattedCount.value = props.useComma ? formatWithCommas(parsedEnd.value) : parsedEnd.value
formattedCount.value = props.useComma ? formatWithCommas(parsedEnd.value) : parsedEnd.value
emit('readyLoop')
return
}
currentCount.value = Math.round(start)
@@ -71,6 +76,10 @@ watch(
() => props.end,
() => {
animateCount()
},
{
deep:true,
immediate:true
}
)
</script>

View File

@@ -5,12 +5,14 @@
<!-- Swiper 轮播容器 -->
<div class="swiper-container" ref="swiperContainer">
<div class="swiper-wrapper">
<div class="banner-block swiper-slide">
<div class="banner-block swiper-slide" :key="surveyStats.user_count">
<p class="banner-block-slogan">实时链接消费者的深度洞察及日常信息采集工具</p>
<div class="banner-block-desc">
已支持 <CountTo :end="surveyStats.user_count" :use-comma="true" /> 用户 |
发起 <CountTo :end="surveyStats.survey_count" :use-comma="true" /> 次调研 |
有效回收 <CountTo :end="surveyStats.sample_count" :use-comma="true" /> 份数据
已支持 <CountTo :end="surveyStats.user_count" :use-comma="true" :key="surveyStats.user_count"
@ready-loop="readyLoop"
/> 用户 |
发起 <CountTo :end="surveyStats.survey_count" :use-comma="true" @ready-loop="readyLoop" /> 次调研 |
有效回收 <CountTo :end="surveyStats.sample_count" :use-comma="true" @ready-loop="readyLoop" /> 份数据
</div>
</div>
<!-- 动态 Banner 列表 -->
@@ -60,7 +62,7 @@
</template>
<script setup>
import { onBeforeUnmount, onMounted, ref } from 'vue';
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import Swiper, { Autoplay } from 'swiper';
import 'swiper/swiper-bundle.css';
import { useRouter } from 'vue-router';
@@ -105,10 +107,22 @@ const getQuesStatics = async () => {
const res = await getQuestionnaireStatistics()
surveyData.value = res.data
}
const initSwiper = ()=>{
const readyLoop = ()=>{
if (bannerSwiper){
bannerSwiper.destroy()
}
initSwiper(true)
}
const initSwiper = (loop = false)=>{
// 初始化 Swiper
if (bannerSwiper) {
bannerSwiper.destroy(true, true);
bannerSwiper = null;
}
bannerSwiper = new Swiper(swiperContainer.value, {
loop: true,
loop,
autoplay: {
delay: 5000,
disableOnInteraction: false