组件解耦:在 Astro 中实现搜索标签自定义
Architecture
Astro TypeScript Component 痛点
目前的 SearchWidget 组件把 Trending 标签硬编码在 HTML 里。这导致首页和博客列表页只能显示相同的内容。首页侧重个人标签,博客页侧重架构和技术栈,组件必须解耦。
实现逻辑
通过 Astro 的 Props 机制,给组件传入一个可选的字符串数组。如果外部没有传入参数,则使用组件内部预设的标签作为兜底。
1. 定义 Props 接口
在组件 Frontmatter 区域定义 Props 接口。使用可选属性 trendingTags?,并配合 TypeScript 声明。
2. 设置默认值
在解构 Astro.props 时直接赋值。这能保证组件在任何页面调用都不会报错。
代码实现
修改 src/components/SearchWidget.astro:
---
interface Props {
trendingTags?: string[];
}
// 解构并设置默认标签
const { trendingTags = ["AI", "Agent", "Dify", "n8n"] } = Astro.props;
import { getCollection } from "astro:content";
const posts = await getCollection("blog");
const allTags = [...new Set(posts.flatMap(post => post.data.tags || []))];
---
<div class="w-full">
<div class="flex flex-wrap gap-2 mt-4">
<span class="text-xs">Trending:</span>
{trendingTags.map((tag) => (
<a
href={`/blog/tag/${tag}`}
class="border border-gray-400 rounded-md px-3 py-1 text-sm hover:bg-black hover:text-white transition-colors"
>
{tag}
</a>
))}
</div>
</div>
页面调用方式
博客列表页 (特定需求) 在 src/pages/blog/[…page].astro 中传入技术类标签:
<SearchWidget trendingTags={["Astro", "Tailwind", "Git", "DevOps"]} />
首页 (默认需求)
首页直接调用,不需要传参,自动展示组件内部定义的默认标签:
<SearchWidget />
这种做法避免了代码重复,修改标签内容时只需在调用处处理,不用动组件底层代码。