50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | IncrementingCounter(递增计数器)
📅 我们继续 50 个小项目挑战!—— IncrementingCounter
组件
仓库地址:https://github.com/SunACong/50-vue-projects
项目预览地址:https://50-vue-projects.vercel.app/
使用 Vue 3 的 Composition API 和 <script setup>
语法结合 TailwindCSS 构建一个带有数字增长动画效果的统计卡片组件。该组件常用于展示社交媒体粉丝数、网站访问量、销售数据等可视化指标。
🎯 组件目标
- 展示多个统计数据项(如 Twitter 关注者、YouTube 订阅数等)。
- 数字从
0
动态增长到指定目标值。 - 使用图标与文字搭配提升视觉识别度。
- 使用 TailwindCSS 快速构建现代 UI 界面。
- 添加生命周期控制防止内存泄漏。
⚙️ 技术实现点
技术点 | 描述 |
---|---|
Vue 3 Composition API (<script setup> ) | 使用响应式变量管理组件状态 |
reactive() 响应式数组 | 存储并更新多个统计项数据 |
onMounted 生命周期钩子 | 在组件挂载后启动动画 |
setInterval 定时器 | 控制数字逐步递增的过程 |
clearInterval | 避免内存泄漏,在组件卸载时清除定时器 |
TailwindCSS 布局与样式 | 快速构建美观的统计卡片界面 |
🧱 组件实现
模板结构 <template>
<template><div class="flex h-screen items-center justify-center gap-20 text-white"><divclass="flex flex-col items-center justify-center gap-2"v-for="item in iconList":key="item.id"><img :src="item.icon" alt="icon" class="h-20 w-20" /><div class="text-3xl font-extrabold">{{ item.count }}</div><div class="font-mono">{{ item.name }}</div></div></div>
</template>
脚本逻辑 <script setup>
<script setup>
import { ref, onMounted, onUnmounted, reactive } from 'vue'const iconList = reactive([{id: 1,name: 'Twitter Followers',count: 0,icon: '/src/assets/icon/推特.svg',target: 12000,},{id: 2,name: 'Facebook Fans',count: 0,icon: '/src/assets/icon/facebook.svg',target: 5000,},{id: 3,name: 'YouTube Subscribers',count: 0,icon: '/src/assets/icon/油管.svg',target: 7000,},
])onMounted(() => {const totalSteps = 100 // 总步数const intervalDuration = 10 // 每次间隔时间(毫秒)let currentStep = 0const interval = setInterval(() => {currentStep++iconList.forEach((item) => {const stepValue = Math.ceil(item.target / totalSteps) // 每步增长的值item.count = Math.min(item.count + stepValue, item.target) // 确保不超过目标值})if (currentStep >= totalSteps) {clearInterval(interval)}}, intervalDuration)onUnmounted(() => {clearInterval(interval)})
})
</script>
🔍 重点效果实现
✅ 数字增长动画原理
通过 setInterval
设置了一个定时器,每 10ms 执行一次:
iconList.forEach((item) => {const stepValue = Math.ceil(item.target / totalSteps)item.count = Math.min(item.count + stepValue, item.target)
})
- 将目标值平均分成
totalSteps
步; - 每次增加一步的数值;
- 最终达到目标值,并停止计时器。
这样就能实现一个平滑的数字增长动画。
💡 组件卸载清理机制
为避免内存泄漏,我们在 onUnmounted
中调用 clearInterval
:
onUnmounted(() => {clearInterval(interval)
})
确保组件卸载时自动清除定时器。
🎨 TailwindCSS 样式重点讲解
类名 | 作用 |
---|---|
flex , items-center , justify-center | 居中布局整个容器 |
h-screen | 高度为视口全高 |
gap-20 | 元素之间间距为 5rem |
flex-col | 设置为纵向排列 |
h-20 , w-20 | 图标大小为 5rem × 5rem |
text-3xl | 字体大小为 1.875rem |
font-extrabold | 加粗字体 |
font-mono | 使用等宽字体 |
text-white | 设置文字颜色为白色 |
这些 Tailwind 工具类帮助我们快速构建了一个视觉清晰、层次分明的统计信息展示区域。
📁 常量定义 + 组件路由
✅ 常量定义(可选)
constants/index.js
添加组件预览常量:
{id: 15,title: 'Incrementing Counter',image: 'https://50projects50days.com/img/projects-img/15-incrementing-counter.png',link: 'IncrementingCounter',},
router/index.js
中添加路由选项:
{path: '/IncrementingCounter',name: 'IncrementingCounter',component: () => import('@/projects/IncrementingCounter.vue'),}
🏁 总结
数据统计卡片组件涵盖了Vue 3 的响应式系统、定时器控制、生命周期管理和 TailwindCSS 的灵活样式组合。
👉 下一篇,我们将完成DrinkWater
组件,一个交互式的喝水记录以及达成目标的组件,具有丝滑的交互动画!🚀