50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DrinkWater(喝水记录组件)

📅 我们继续 50 个小项目挑战!------ DrinkWater组件

仓库地址:https://github.com/SunACong/50-vue-projects

项目预览地址:https://50-vue-projects.vercel.app/


使用 Vue 3 的 Composition API 和 <script setup> 语法结合 TailwindCSS 构建一个互动式的"每日喝水进度追踪"组件。用户可以通过点击玻璃杯按钮来更新已喝水量,并实时看到水位上升动画和剩余水量变化。

🎯 组件目标

  • 显示每日喝水目标为 2 升(2000ml)
  • 每个杯子代表 250ml
  • 点击杯子增加当前饮水量
  • 动态显示剩余水量和已喝水量
  • 使用 TailwindCSS 快速构建现代 UI 界面
  • 添加水位上升动画效果

⚙️ 技术实现点

技术点 描述
Vue 3 Composition API (<script setup>) 使用响应式变量管理组件状态
ref 响应式变量 控制当前饮水量
@click 事件绑定 用户点击玻璃杯触发饮水动作
:style 动态绑定样式 控制水位高度
v-if 条件渲染 只有喝水后才显示已喝水量
TailwindCSS 动画与布局 构建美观的交互界面

🧱 组件实现

模板结构 <template>

vue 复制代码
<template>
    <div class="flex h-screen flex-col items-center justify-center gap-8 text-white">
        <h1 class="font-mono text-3xl">Drink Water</h1>
        <h3 class="font-mono">Goal: 2 Liters</h3>

        <div
            class="relative flex h-1/4 w-32 flex-col items-center justify-center rounded-b-3xl border-2 text-center overflow-hidden">
            <!-- 水的进度条 -->
            <div 
                class="absolute bottom-0 left-0 right-0 bg-blue-500 transition-all duration-500 ease-out"
                :style="{ height: `${currentAmount / 8 * 100}%` }"
            ></div>
            
            <!-- 剩余水量显示 -->
            <div class="relative z-10">
                <div class="text-2xl">{{ (2000 - currentAmount * 250) / 1000 }}L</div>
                <div>Remained</div>
            </div>

            <!-- 已喝水量显示 -->
            <div class="absolute top-2 text-lg font-bold" v-if="currentAmount > 0">
                {{ currentAmount * 250 }}ml
            </div>
        </div>

        <p class="font-mono">Select how many glasses of water that you have drank</p>

        <div class="flex flex-wrap items-center justify-center gap-4">
            <div
                :class="[
                    'h-24 w-8 basis-1/5 cursor-pointer rounded-b-2xl border-2 pt-5 text-center transition-all duration-300 ease-in-out',
                    item <= currentAmount ? 'bg-blue-500' : 'bg-gray-500',
                ]"
                v-for="item in 8"
                :key="item"
                @click="drink(item)">
                250 ml
            </div>
        </div>
    </div>
</template>

脚本逻辑 <script setup>

vue 复制代码
<script setup>
import { ref, onMounted, onUnmounted, reactive } from 'vue'

const currentAmount = ref(0) // 当前水量(单位:杯数)

const drink = (amount) => {
    currentAmount.value = amount
}
</script>

🔍 重点效果实现

✅ 水杯点击交互

每个水杯表示 250ml,共 8 杯达成 2000ml:

html 复制代码
<div
    v-for="item in 8"
    :key="item"
    @click="drink(item)">

点击任意一杯时,将当前水量设置为该杯对应数值。

💧 水位动态增长动画

我们通过 :style 动态控制水位高度:

html 复制代码
<div 
    :style="{ height: `${currentAmount / 8 * 100}%` }"
></div>

并配合 Tailwind 的过渡类实现平滑动画:

html 复制代码
transition-all duration-500 ease-out

📊 剩余水量计算展示

通过公式计算出剩余水量并以升为单位显示:

html 复制代码
{{ (2000 - currentAmount * 250) / 1000 }}L

🖼️ 水杯状态视觉反馈

根据是否已点击,切换背景颜色:

html 复制代码
:class="[item <= currentAmount ? 'bg-blue-500' : 'bg-gray-500']"

🎨 TailwindCSS 样式重点讲解

类名 作用
flex, items-center, justify-center 居中布局整个容器
h-screen, flex-col 全屏高度 + 纵向排列
gap-8 各元素之间间距为 2rem
rounded-b-3xl 底部圆角为 1.5rem
border-2 边框宽度为 2px
overflow-hidden 防止水位溢出容器
h-24, w-8 水杯大小为 6rem × 2rem
pt-5 上内边距为 1.25rem
transition-all duration-500 过渡动画持续时间为 0.5 秒
cursor-pointer 鼠标悬停变为可点击指针
text-2xl, text-lg 不同层级字体大小
font-bold, font-mono 加粗或等宽字体

这些 Tailwind 工具类帮助我们快速构建了一个互动性强、视觉反馈明确的喝水追踪组件。


📁 常量定义 + 组件路由

constants/index.js 添加组件预览常量:

js 复制代码
{
        id: 16,
        title: 'Drink Water',
        image: 'https://50projects50days.com/img/projects-img/16-drink-water.png',
        link: 

router/index.js 中添加路由选项:

js 复制代码
{
        path: '/DrinkWater',
        name: 'DrinkWater',
        component: () => import('@/projects/DrinkWater.vue'),
    },

🏁 总结

喝水进度追踪组件不仅功能实用,非常适合用于健康类应用、习惯养成类仪表盘或个人追踪页面。

你可以进一步扩展的功能包括:

  • 支持本地存储记录每天饮水情况
  • 添加"重置今日饮水"按钮
  • 支持图表可视化统计趋势
  • 支持通知提醒喝水
  • 支持主题切换(暗色/亮色)

👉 下一篇,我们将完成MovieApp组件,一个常见的电影网站常用的卡片式展示,利用tailwindcss可以轻松实现票的布局和排版!🚀

相关推荐
Qrun14 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp15 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
charlie1145141913 小时前
CSS笔记4:CSS:列表、边框、表格、背景、鼠标与常用长度单位
css·笔记·学习·css3·教程
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front8 小时前
在职场生存中如何做个不好惹的人
前端