723 字
4 分钟
从零加一个打赏页:配置驱动、二态卡片与页面可用性体系

需求与形态#

打赏页 /sponsor/ 要承载三件事:怎么赏(收款码 / 跳转链接)、谁赏过(打赏者名单)、赏金用哪(用途说明)。整页 SSR 渲染零水合——打赏不需要任何客户端交互逻辑,纯静态卡片就够了。

数据模型:二态卡片#

打赏方式抽象成 SponsorMethod,一个联合类型覆盖两种形态:

type SponsorMethod =
| { type: "qrcode"; name: string; image: string }
| { type: "url"; name: string; url: string };
  • qrcode → 扫码卡:图片强制白底 + 0.75rem 内边距。这是内容性例外——微信收款码是黑块码,深色模式下若透出页面底色就扫不出来了,注释里专门写明这里不许跟暗色主题;
  • url → 外链卡:主色「前往打赏」按钮,hover brightness(1.08)、按下 scale(0.97)

两者缺一个字段的直接在 resolveSponsorMethods() 里过滤掉,半残数据不渲染。

配置驱动 + 内容仓管理#

全部配置收在内容仓 sponsor.yaml,经 withUserConfig("sponsor") 覆盖主题默认(默认 enable: false):

enable: true
methods:
- type: qrcode
name: 微信
image: /images/sponsor/wechat.png
- type: qrcode
name: 支付宝
image: /images/sponsor/alipay.png
donors:
- name: 某位小伙伴
amount: 50
date: 2026-08-15

图片路径解析三态:/ 开头走 url() 适配 base path,http(s):/data: 原样,其余走构建期 resolveAsset()。收款码图片放内容仓 public/images/sponsor/——收款码属于站点内容,跟着内容仓走。

打赏者名单#

SponsorDonor { name, amount?, date?, avatar? } 渲染成 auto-fill minmax(13rem, 1fr) 网格,细节:

  • 无头像取首字符占位(CSS 变量 --initial 喂给伪元素);
  • 日期用 Intl.DateTimeFormat(siteConfig.lang) 按站点语言本地化;
  • 金额 font-variant-numeric: tabular-nums 等宽数字 + 主色——纵向看一列金额不会跳。

关键设计:页面可用性双重门控#

新页面最容易漏的是「关掉之后呢」。这个主题有一套统一的页面可用性体系:

// 页面可用 = 页面开关 × 功能开关
siteConfig.pages.sponsor && sponsorConfig.enable

任一为 false:路由跳 /404/、顶栏与移动抽屉的导航入口自动隐藏、组件零 DOM。两层开关各管一层——pages.sponsor 是「这个页面要不要存在」,sponsorConfig.enable 是「打赏功能本身开不开」。

视觉收尾#

圆角卡 + 描边沿用全站 M3E 令牌;用途说明做成 primary-container 底色的胶囊提示条;爱心 badge 是主色圆角方块图标——整页只有一个主色重点(打赏按钮),视线动线:方式 → 名单 → 按钮。

小结#

打赏页 200 行内搞定:二态卡片数据模型、内容仓配置驱动、SSR 零水合。真正值得复用的是页面可用性体系——任何新页面接进来,路由 404、导航隐藏、零 DOM 三件事自动成立。

从零加一个打赏页:配置驱动、二态卡片与页面可用性体系
https://blog.fqzlr.top/posts/tech/sponsor-page-from-scratch/
作者
fqzlr
发布于
2026-09-05
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取