页面骨架统一之后,下一个最容易重复的地方就是 section 标题。
当前站点里,下面这些地方都在反复出现同一类结构:
- 首页区块标题 + 右侧“查看全部”
- 系列详情页区块标题 + 简介
- 归档总览标题
- 索引页每个月分组的标题 + 右侧计数
这些结构表面不同,底层其实都在回答同一个问题:
- 这一段叫什么
- 它有没有补充说明
- 右边有没有动作或统计
- 标题旁边有没有附加状态
所以这次把它抽成了:
src/components/layout/PageSectionHeader.astro
组件既支持 props,也支持 slot
如果只靠 props,这个组件会很快长出一堆分支;如果只靠 slot,又会失去常见结构的便利。
当前做法是把最常见的情况做成 props:
interface Props {
title: string;
intro?: string;
actionHref?: string;
actionLabel?: string;
headingTag?: "h2" | "h3";
className?: string;
}
同时再开放两个 slot:
title-suffixaside
这样首页这种“标题 + 右侧链接”只用 props 就够了,而归档索引分组这种“标题 + continuation + 右侧计数”则可以通过 slot 完成。
首页和索引分组终于不再各写一套 header
首页现在可以直接写成:
<PageSectionHeader
title={copy.index.latestArticlesHeading}
actionHref={getArticlesPath()}
actionLabel={copy.index.browseArticles}
/>
而索引列表分组则是:
<PageSectionHeader title={group.label}>
{group.isContinuation ? (
<span slot="title-suffix" class="content-index-continuation">{continuationLabel}</span>
) : null}
<p slot="aside" class="content-index-count">{getGroupCountLabel(group.totalCount)}</p>
</PageSectionHeader>
这两种场景共享了一套组件,却没有被迫长成完全一样的内容结构。
它解决的是“区块入口的一致性”
这个组件的价值不在于少写几十行 JSX/Astro 模板,而在于:
- 首页 section 的标题结构稳定了
- 系列详情页的小标题和说明不会再单独长出一套样式
- 归档和文章列表分组的计数区也能接入同一个壳
于是页面内部的“段落组织方式”开始一致:
- 外层 section 统一
- 区块 header 统一
- 真正变化的只剩内容列表本身
为什么这一步值得单独抽
站点后面只会继续增加 section,而不是减少。
如果不把这层抽出来,新增页面时很容易继续复制这些结构:
- 一个
div.page-section-header - 一个
div.page-section-header-row - 一个
h2 - 一个
a或一个右侧统计
短期看不明显,长期就会让页面组合越来越松散。
PageSectionHeader 的作用,就是把“section 的开头该怎么长”这件事先固定下来。后面不管 section 内容是卡片、索引列表还是统计卡,都能站在同一块骨架上。