50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | IncrementingCounter(递增计数器)

发布于:2025-06-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

📅 我们继续 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">
        <div
            class="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 = 0

    const 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组件,一个交互式的喝水记录以及达成目标的组件,具有丝滑的交互动画!🚀


网站公告

今日签到

点亮在社区的每一天
去签到