实现今日一言功能
615 字
3 分钟
实现今日一言功能
创建数据文件
文件路径:src/content/ziyuan/ 目录并添加文件:quote.md
---title: "每日一言"quotes: - text: "生活不是等待暴风雨过去,而是学会在雨中跳舞。" author: "塞维涅夫人" - text: "世界上只有一种英雄主义,就是在认清生活真相之后依然热爱生活。" author: "罗曼·罗兰"---创建组件文件
文件路径:src/components/widget/QuoteOfTheDay.astro
---import WidgetLayout from "@/components/common/WidgetLayout.astro";import { getCollection } from "astro:content";
// 从 content/ziyuan/quote.md 读取名言数据const ziyuanEntries = await getCollection("ziyuan");const quoteEntry = ziyuanEntries.find((e) => e.id === "quote");const quoteData = quoteEntry?.data as any;const quotes = quoteData?.quotes || [];
interface Props { class?: string; style?: string;}
const { class: className, style } = Astro.props;
// 使用日期作为随机种子,确保同一天显示相同的名言const today = new Date();const dateStr = today.toISOString().split("T")[0];const seed = dateStr.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);const randomIndex = seed % quotes.length;const quote = quotes[randomIndex] || { text: "暂无名言", author: "" };---
<WidgetLayout name="✨ 今日一言" id="quote-of-the-day" class={className} style={style}> <div class="quote-content"> <blockquote class="quote-text"> <span class="quote-mark">"</span> {quote.text} <span class="quote-mark">"</span> </blockquote> <cite class="quote-author">—— {quote.author}</cite> </div></WidgetLayout>
<style> .quote-content { display: flex; flex-direction: column; gap: 0.75rem; padding: 0.5rem 0; }
.quote-text { position: relative; font-style: italic; font-size: 0.9rem; line-height: 1.6; color: var(--text-color); padding: 0 0.5rem; margin: 0; }
.quote-mark { font-size: 1.5rem; line-height: 0; vertical-align: middle; color: var(--primary); opacity: 0.6; font-family: Georgia, serif; }
.quote-author { display: block; text-align: right; font-size: 0.75rem; color: var(--content-meta); font-style: normal; margin-top: 0.25rem; }
/* 深色模式优化 */ :global(html.dark) .quote-text { color: var(--text-color); }
/* 悬停效果 */ :global(.quote-content:hover .quote-text) { color: var(--primary); transition: color 0.2s ease; }</style>配置数据加载方式
在 src/content.config.ts 配置数据加载方式:
const ziyuanCollection = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/ziyuan" }), schema: z.union([ z.object({ title: z.string(), content: z.string(), closable: z.boolean().optional().default(true), link: z .object({ enable: z.boolean().optional().default(true), text: z.string(), url: z.string(), external: z.boolean().optional().default(false), }) .optional(), quotes: z.undefined().optional(), }), z.object({ title: z.string(), quotes: z.array( z.object({ text: z.string(), author: z.string(), }) ), content: z.undefined().optional(), closable: z.undefined().optional(), link: z.undefined().optional(), }), ]),});
export const collections = { ziyuan: ziyuanCollection,};注册组件
文件路径:src/components/layout/SideBar.astro
import QuoteOfTheDay from "@/components/widget/QuoteOfTheDay.astro";添加到组件映射表:
const componentMap = { quoteOfTheDay: QuoteOfTheDay, // 添加这一行};侧边栏配置
文件路径:src/config/sidebarConfig.ts
- 添加到右侧边栏
rightComponents: [ { type: "quoteOfTheDay", // 必须与 componentMap 的 key 一致 enable: true, // true = 启用,false = 禁用 position: "sticky", // "top" = 固定顶部,"sticky" = 粘性定位 showOnPostPage: true, // 是否在文章详情页显示 }, // ... 其他组件],- 添加到移动端底部
mobileBottomComponents: [ { // 组件类型:今日一言 type: "quoteOfTheDay", // 是否启用该组件 enable: true, // 是否在文章详情页显示 showOnPostPage: true, }, // ... 其他组件],类型定义
文件路径:src/types/config.ts
export type WidgetComponentType = | "profile" | "announcement" // ... 其他类型 | "quoteOfTheDay"; // 确保这一行存在支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!