恋爱计时组件

701 字
4 分钟
恋爱计时组件

创建组件#

文件路径:src/components/widget/RelationshipTimer.astro

<!-- 恋爱倒计时组件 -->
---
import WidgetLayout from "@/components/common/WidgetLayout.astro";
import { relationshipConfig } from "@/config/relationshipConfig";
const config = relationshipConfig;
interface Props {
class?: string;
style?: string;
}
const className = Astro.props.class;
const style = Astro.props.style;
---
<WidgetLayout
name={config.title || "恋爱时光"}
id="relationship"
class={className}
style={style}
>
<div class="flex flex-col items-center p-2">
<!-- 顶部名称栏 -->
<div class="flex items-center justify-center gap-2 mb-4 text-sm font-medium text-neutral-600 dark:text-neutral-400">
<span>{config.name1}</span>
<span class="text-red-500 animate-pulse">❤️</span>
<span>{config.name2}</span>
</div>
<!-- 头像和爱心 -->
<div class="flex items-center justify-center gap-4 mb-6">
<div class="w-16 h-16 rounded-full overflow-hidden border-2 border-white dark:border-neutral-800 shadow-md transition-transform hover:scale-110">
<img src={config.avatar1} alt={config.name1} class="w-full h-full object-cover" />
</div>
<div class="text-2xl text-red-500 transform transition-all hover:scale-125 hover:rotate-12 cursor-pointer">
❤️
</div>
<div class="w-16 h-16 rounded-full overflow-hidden border-2 border-white dark:border-neutral-800 shadow-md transition-transform hover:scale-110">
<img src={config.avatar2} alt={config.name2} class="w-full h-full object-cover" />
</div>
</div>
<!-- 计时器 -->
<div class="relationship-timer flex items-center justify-center gap-x-1 text-sm whitespace-nowrap overflow-x-auto">
<span class="timer-num" data-timer-years>0</span><span class="timer-unit bg-red-400">年</span>
<span class="timer-num" data-timer-months>0</span><span class="timer-unit bg-red-300">月</span>
<span class="timer-num" data-timer-days>0</span><span class="timer-unit bg-blue-400">天</span>
<span class="timer-num" data-timer-hours>0</span><span class="timer-unit bg-orange-400">时</span>
<span class="timer-num" data-timer-minutes>0</span><span class="timer-unit bg-blue-500">分</span>
<span class="timer-num" data-timer-seconds>00</span><span class="timer-unit bg-purple-400">秒</span>
</div>
</div>
</WidgetLayout>
<style>
@reference "tailwindcss";
.timer-num {
@apply font-bold text-neutral-700 dark:text-neutral-200 min-w-[0rem] text-center;
color: var(--primary);
}
.timer-unit {
@apply px-1 py-0.5 rounded text-[10px] text-white font-medium shrink-0;
}
</style>
<script is:inline define:vars={{ startDateStr: config.startDate }}>
function updateRelationshipTimer() {
const startDate = new Date(startDateStr);
const now = new Date();
let diff = now.getTime() - startDate.getTime();
if (diff < 0) return;
// 计算年月日时分秒的差值
let years = now.getFullYear() - startDate.getFullYear();
let months = now.getMonth() - startDate.getMonth();
let days = now.getDate() - startDate.getDate();
let hours = now.getHours() - startDate.getHours();
let minutes = now.getMinutes() - startDate.getMinutes();
let seconds = now.getSeconds() - startDate.getSeconds();
// 处理借位逻辑
if (seconds < 0) {
seconds += 60;
minutes--;
}
if (minutes < 0) {
minutes += 60;
hours--;
}
if (hours < 0) {
hours += 24;
days--;
}
if (days < 0) {
const lastMonth = new Date(now.getFullYear(), now.getMonth(), 0);
days += lastMonth.getDate();
months--;
}
if (months < 0) {
months += 12;
years--;
}
// 更新所有实例,避免移动端和电脑端 ID 冲突
const update = (attr, value) => {
const elements = document.querySelectorAll(`[data-timer-${attr}]`);
elements.forEach(el => {
el.innerText = value;
});
};
update('years', years);
update('months', months);
update('days', days);
update('hours', hours);
update('minutes', minutes);
update('seconds', seconds.toString().padStart(2, '0'));
}
// 立即运行并每秒更新
updateRelationshipTimer();
if (!window.relationshipTimerInterval) {
window.relationshipTimerInterval = setInterval(updateRelationshipTimer, 1000);
}
// 监听 Swup 页面切换
document.addEventListener('swup:content:replace', updateRelationshipTimer);
</script>

注册组件#

文件路径:src/components/layout/SideBar.astro

---
import RelationshipTimer from "@/components/widget/RelationshipTimer.astro"; // 引入恋爱计时组件
---
// 组件映射表
const componentMap = {
<!-- 恋爱计时组件 -->
relationship: RelationshipTimer,
} satisfies Record<WidgetComponentType, typeof Profile>;

启用组件#

文件路径:src/config/sidebarConfig.ts

  • 右侧边栏配置
{
type: "relationship", // 组件类型,与 componentMap 中的 key 对应
enable: true, // 是否启用
position: "top", // 组件位置:top(固定顶部)或 sticky(粘性定位)
showOnPostPage: true, // 是否在文章详情页显示
},
  • 移动端配置
{
// 组件类型:恋爱计时小组件
type: "relationship",
// 是否启用该组件
enable: true,
// 是否在文章详情页显示
showOnPostPage: true,
},

配置类型定义#

文件路径:src/types/config.ts

// 组件配置类型定义
export type WidgetComponentType =
| "relationship";

双方信息配置#

文件路径:src/config/relationshipConfig.ts

import type { RelationshipConfig } from "../types/config";
export const relationshipConfig: RelationshipConfig = {
// 恋爱开始日期
startDate: "2026-01-06",
// 双方名称
name1: "---------TSH",
name2: "CXY---------",
// 双方头像
avatar1: "https://re.tsh520.cn/zl/tsh.jpg",
avatar2: "https://re.tsh520.cn/zl/cxy.jpg",
// 小组件标题
title: "我和宝宝在一起已经",
};

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
恋爱计时组件
https://hyde.seasir.top/blog/RelationshipTimer/
作者
Hyde
发布于
2026-06-02
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Hyde
Hello, I'm Hyde.
📢 欢迎来访者
👋🏻 Hi,我是Hyde,欢迎您!
分类
标签
站点统计
文章
9
分类
2
标签
3
总字数
3,019
运行时长
0
最后活动
0 天前
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
我和宝宝在一起已经
---------TSH ❤️ CXY---------
---------TSH
❤️
CXY---------
0 0 0 0 0 00
✨ 今日一言
" 人生如逆旅,我亦是行人。 "
—— 苏轼
统计

文章目录

✨️ 复制成功,转载请标注本文地址