组件解耦:在 Astro 中实现搜索标签自定义

组件解耦:在 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 />

这种做法避免了代码重复,修改标签内容时只需在调用处处理,不用动组件底层代码。

© 2026 Personal Website
Developed by Ryan 🫡