📅 我们继续 50 个小项目挑战!—— ThemeClock组件

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

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

在这里插入图片描述


使用 Vue 3 的 Composition API 和 <script setup> 语法结合 TailwindCSS 构建一个能够动态切换主题(深色与浅色)的时钟组件。该组件不仅显示当前时间(包括小时、分钟和秒),还展示了今天的日期和星期。


🎯 组件目标

  • 动态切换主题(深色/浅色)
  • 显示当前的时间(小时、分钟、秒针)
  • 展示今日日期和星期
  • 使用 CSS 变换实现指针旋转效果
  • 基于 Vue 3 和 TailwindCSS 实现响应式设计

⚙️ 技术实现点

技术点描述
Vue 3 Composition API (<script setup>)使用响应式变量管理组件状态
ref 响应式变量控制时间状态、主题模式
onMountedonUnmounted 生命周期钩子定时更新时间状态
TailwindCSS 自定义样式快速构建现代 UI 界面
@click 事件绑定切换主题逻辑

🧱 组件实现

模板结构 <template>

<template><div:class="['min-h-screen',theme === 'dark' ? 'bg-gray-900 text-white' : 'bg-gray-100 text-gray-900','flex flex-col items-center justify-center',]"><!-- 主题切换按钮 --><button@click="toggleTheme":class="['mb-8 rounded-md p-2',theme === 'dark' ? 'bg-gray-700 hover:bg-gray-600' : 'bg-white hover:bg-gray-200',]">{{ theme === 'dark' ? '切换至浅色主题' : '切换至深色主题' }}</button><!-- 时钟容器 --><div class="relative h-64 w-64"><!-- 表盘 --><div:class="['absolute inset-0 rounded-full',theme === 'dark' ? 'bg-gray-800' : 'bg-white',]"><!-- 时针、分针、秒针及中心圆点 --><!-- ... (省略部分代码) ... --></div></div><!-- 日期与星期 --><div:class="['mt-8 text-xl font-semibold',theme === 'dark' ? 'text-gray-300' : 'text-gray-800',]">{{ currentDate }} {{ currentDay }}</div></div>
</template>

脚本逻辑 <script setup>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'// 主题切换
const theme = ref('dark')
const toggleTheme = () => {theme.value = theme.value === 'dark' ? 'light' : 'dark'
}// 时间状态
const hoursRotation = ref(0)
const minutesRotation = ref(0)
const secondsRotation = ref(0)
const currentDate = ref('')
const currentDay = ref('')// 更新时间函数
const updateTime = () => {const now = new Date()const hours = now.getHours()const minutes = now.getMinutes()const seconds = now.getSeconds()const hoursForClock = hours % 12hoursRotation.value = hoursForClock * 30 + minutes * 0.5minutesRotation.value = minutes * 6 + seconds * 0.1secondsRotation.value = seconds * 6console.log(hoursRotation.value, minutesRotation.value, secondsRotation.value)const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']currentDate.value = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`currentDay.value = days[now.getDay()]
}// 启动定时器
let interval = null
onMounted(() => {updateTime()interval = setInterval(updateTime, 1000)
})// 清除定时器
onUnmounted(() => {clearInterval(interval)
})
</script>

🔍 重点效果实现

✅ 动态主题切换

通过 theme 变量来控制整个应用的主题,并且根据其值动态修改类名:

:style="{transform: `translateY(-50%) rotate(${hoursRotation - 90}deg)`,
}"

当用户点击“切换主题”按钮时,调用 toggleTheme() 方法切换主题模式。

💡 指针旋转动画

使用 CSS 变换来实现指针的旋转效果。例如,时针的旋转角度计算如下:

hoursRotation.value = hoursForClock * 30 + minutes * 0.5

每个小时对应的角度是 30 度(360度/12小时),并且为了更加精确,我们还会加上由分钟数决定的部分角度。

🖼️ 日期与星期展示

利用 JavaScript 的 Date 对象获取当前的日期和星期,然后以友好的格式展示给用户:

currentDate.value = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()
).padStart(2, '0')}`
currentDay.value = days[now.getDay()]

你说得对,让我们补充一下 🎨 TailwindCSS 样式重点讲解 部分,详细解释在这个时钟组件中使用的 TailwindCSS 类及其作用。


🎨 TailwindCSS 样式重点讲解

以下是针对该时钟组件所用到的 TailwindCSS 工具类的详细解释:

类名作用
min-h-screen设置最小高度为视口高度,确保组件至少占据整个屏幕的高度。
bg-gray-900 text-white / bg-gray-100 text-gray-900分别设置背景颜色和文本颜色,前者用于深色主题,后者用于浅色主题。
flex flex-col items-center justify-center使用 Flexbox 布局,使内容垂直和水平居中,并按列排列。
mb-8 rounded-md p-2外边距底部设为 mb-8,圆角设为 rounded-md,内边距设为 p-2
bg-gray-700 hover:bg-gray-600 / bg-white hover:bg-gray-200按钮的背景颜色及悬停时的颜色变化,分别对应深色和浅色主题下的样式。
relative h-64 w-64设置相对定位,宽高均为 64 单位,用于创建一个固定大小的表盘容器。
absolute inset-0 rounded-full绝对定位并铺满父容器,同时将元素裁剪成圆形。
h-1 w-1/4 origin-left rounded-full bg-current定义时针的宽度、长度、旋转中心点以及圆角样式。bg-current 表示使用当前元素的文字颜色作为背景颜色。
translateY(-50%) rotate(${hoursRotation - 90}deg)利用 CSS 变换函数调整指针的位置和旋转角度。
h-px w-1/2 origin-left rounded-full bg-red-500秒针的特殊样式,其中 h-px 创建了一个极细的秒针,bg-red-500 设置了红色。
h-3 w-3 -translate-x-1/2 -translate-y-1/2 transform rounded-full中心圆点的样式,通过平移将其精确放置在表盘中心。
text-xl font-semibold设置日期与星期部分的字体大小和粗细。
text-gray-300 / text-gray-800根据主题模式设置日期与星期部分的文本颜色。

📁 常量定义 + 组件路由

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

{id: 19,title: 'Theme Clock',image: 'https://50projects50days.com/img/projects-img/19-theme-clock.png',link: 'ThemeClock',},

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

{path: '/ThemeClock',name: 'ThemeClock',component: () => import('@/projects/ThemeClock.vue'),},

📁 扩展功能

此组件可以进一步扩展的功能包括:

  • 自定义表盘样式:可以根据个人喜好调整表盘的颜色、大小等。
  • 添加闹钟或倒计时功能:为时钟组件增加实用功能。
  • 国际化支持:支持多语言,特别是日期和星期的本地化。
  • 响应式设计:优化不同屏幕尺寸下的显示效果。

🏁 总结

👉 下一篇,我们将完成ButtonRippleEffect组件,一个简单的按钮组件,点击有水波的效果。🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86866.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86866.shtml
英文地址,请注明出处:http://en.pswp.cn/web/86866.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

直播预告丨聊聊Milvus 2.6新功能及背后的开发故事

7 月 1 日晚上 20:00-21:00&#xff0c;Zilliz 视频号直播间&#xff0c;Zilliz 合伙人和研发VP 栾小凡将带来《一步到位&#xff0c;详解 Milvus 2.6 新功能》的分享&#xff0c;带你拆解 Milvus 2.6 四大突破&#xff1a; 降本增效的底层架构开发者生产力拉满的新功能性能不打…

pyenv-win 配置指南​

在 Python 开发过程中&#xff0c;经常会遇到需要使用不同版本 Python 的情况。比如&#xff0c;旧项目依赖某个特定的 Python 版本&#xff0c;而新项目则要求使用更新的版本。这时&#xff0c;版本管理工具就显得尤为重要。pyenv-win就是一款专门为 Windows 系统设计的 Pytho…

MongoDB 常见查询语法与命令详解

MongoDB 作为文档型数据库&#xff0c;其查询语言基于 BSON&#xff08;二进制 JSON&#xff09;格式&#xff0c;与传统关系型数据库的 SQL 语法有较大差异。 一、基本查询命令 1. find()&#xff1a;查询文档 语法&#xff1a;db.collection.find(查询条件, 投影)示例&…

AlpineLinux安装docker

或许你在docker中使用 Alpine Linux 的镜像使用得多,但是有没有想过在 Alpine Linux 上安装 Docker 来使用呢?默认情况下,Docker 包位于社区仓库中,因此在使用包管理来安装docker之前建议更换为国内源,并开启社区仓库的链接。 下面的操作是在root用户下运行的,如果要使用…

docker安装gitlab并配置ssl证书

本篇安装环境 Docker版本&#xff1a;Docker version 28.3.0 域名&#xff1a;test.disallow.cn 自签证书&#xff1a;/etc/gitlab/ssl&#xff08;已经存放在该目录&#xff09; 一、拉取镜像 docker run -itd \--privilegedtrue \--hostname gitlab.test.disallow.cn \--p…

Java开发者转型AI时代的路径

Java开发者转型AI时代的路径 引言 随着人工智能技术的飞速发展&#xff0c;AI已不再是遥不可及的未来&#xff0c;而是深刻影响着各行各业的当下。对于Java开发者而言&#xff0c;面对AI浪潮&#xff0c;如何顺势而为&#xff0c;实现职业转型与技能升级&#xff0c;成为摆在…

QT6 源(140)模型视图架构里的视图总基类 QAbstractItemView:

&#xff08;1&#xff09;先给出本类的继承关系 &#xff1a; &#xff08;2&#xff09;Qt 已经预先为视图定义了键盘功能&#xff0c;Qt 大师们通过编程&#xff0c;已经完善了视图对键盘的响应操作 &#xff1a; &#xff08;3&#xff09;因为本类是抽象基类&#xff0c;无…

vue上传各种文件,并预览组件,(预览,下载),下载resources目录下文件

前端组件vue 最终效果 <template><div ><div class"file-list" v-if"existingFiles.length > 0"><div class"file-card" v-for"(file, index) in existingFiles" :key"file.id"><div clas…

【CS创世SD NAND征文】SD NAND赋能新一代儿童智能玩具

基于全志F1C100S的高可靠存储方案 文章目录 基于全志F1C100S的高可靠存储方案[toc]前言 一、应用产品介绍&#xff1a;儿童智能玩具的需求演变二、技术方案介绍&#xff1a;构建智能玩具的"大脑"与"记忆库"三、核心技术模块分析3.1 主控芯片&#xff1a;全…

mac触摸板设置右键

在 Mac 笔记本上&#xff0c;触摸板默认没有物理左右键分区&#xff0c;但可以通过以下方式实现“右键”功能&#xff08;称为 辅助点按&#xff09;&#xff1a; 一、启用与使用右键&#xff08;辅助点按&#xff09; 步骤1&#xff1a;检查系统设置 点击屏幕左上角 &#x…

稳定币发行量创纪录地超过 Visa 交易量

稳定币发行量创纪录地超过 Visa 交易量 稳定币的崛起正在重塑全球金融格局&#xff0c;华夏基金首席执行官甘天&#xff08;Gan Tian&#xff09;强调了稳定币的快速增长&#xff0c;并指出稳定币的交易量在短短五年内就超过了Visa 40年的交易量。这凸显了货币使用的转变。 稳…

编程 IDE 混战简史:从 Copilot 到 Claude Code,一场重塑开发方式的战争

unsetunset引言&#xff1a;开发新纪元的序幕unsetunset 编程世界&#xff0c;从最初依赖打孔卡和简陋的命令行工具&#xff0c;到如今功能琳琅满目的集成开发环境&#xff08;IDE&#xff09;&#xff0c;每一步都见证了效率与智能的飞跃。IDE作为开发者与代码交互的核心界面&…

软测八股--计算机网络

计算机网络基础 局域网广域网 局域网&#xff1a;一个区域内由多台计算机互联成的计算机组&#xff08;学校&#xff0c;办公室&#xff0c;公司/学校等&#xff09;。可以实现文件管理&#xff0c;应用软件管理&#xff0c;答应及管理&#xff0c;扫描仪共享等。是封闭的&am…

某省职业院校技能大赛 高职组“信息安全管理与评估”赛项第二部分:应急响应

&#xff01;&#xff01;&#xff01;需要环境可私信博主&#xff01;&#xff01;&#xff01; &#xff01;&#xff01;&#xff01;若有错误欢迎指正&#xff01;:) 序号任务要求1提交攻击者的两个内网IP地址2提交网站管理员用户的用户名和密码3提交黑客得到 mysql 服务的…

OkHttp 简单配置

OkHttpClient 的简单配置&#xff0c;包含重试&#xff0c;线程池 Configuration public class OkHttpConfig {Bean("deSourceOkHttp")public OkHttpClient okHttpClient() {return new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS).readTimeout(3…

群晖nas安装moodle跳坑记录

1&#xff0c;套件里面直接安装 会安装好几个依赖&#xff0c;包括php apach &#xff0c;数据库。这些安装的时间就比较长。 安装完成后自动安装 Moodle。 过程也很长数据库里面的表有接近500张。 2&#xff0c;安装位置 顺便提一下 nas程序的安装位置 这两个位置好像都不是…

鸿蒙HarmonyOS 5小游戏实践:打砖块游戏(附:源代码)

打砖块是一款经典的游戏&#xff0c;它简单易懂却又充满挑战性。本文将介绍如何使用ArkUI框架开发一个完整的打砖块游戏&#xff0c;涵盖游戏逻辑设计、UI实现和交互处理等核心内容。 游戏架构设计 我们的打砖块游戏采用了组件化设计&#xff0c;主要分为两个部分&#xff1a;…

Flutter MobX 响应式原理与实战详解

&#x1f4da; Flutter 状态管理系列文章目录 Flutter 状态管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux) setState() 使用详解&#xff1a;原理及注意事项 InheritedWidget 组件使用及原理 Flutter 中 Provider 的使用、注…

浅谈国产数据库多租户方案:提升云计算与SaaS的资源管理效率

近年来&#xff0c;“数据库多租户”这一概念在技术圈内频频出现&#xff0c;成为云计算和SaaS&#xff08;软件即服务&#xff09;架构中的重要组成部分。多租户架构不仅为企业提供了高效的资源隔离与共享解决方案&#xff0c;还能大幅降低成本&#xff0c;提高系统的可扩展性…

Wpf的Binding

前言 wpf的Binding就像一个桥梁&#xff0c;它的作用就是连接逻辑层与界面层&#xff0c;既能够把逻辑层的数据搬到界面层展示&#xff0c;又能将界面层的数据更改后传递到逻辑层&#xff0c;Binding的数据来源就是Binding的源&#xff0c;数据展示的地方就是Binding的目标。 …