Components First, Then Pages
Lock down the dozen most common components first, then build pages out of them. Do it the other way around and every page grows its own style.
- 同一个按钮在不同页面上圆角、字号、内边距都不一样
- 改一个样式要在七八个文件里各改一遍,还漏了两处
- 让 AI 做新页面,它又造了一套新的卡片样式
This problem is especially sharp in vibecoding. The AI only ever sees the current page — it has no global view — so every page means it reinvents the button. Without a ready-made component set, it will absolutely make its own.
Components-first has a side benefit: it turns a design decision from "every time" into "once." Once the button's corner radius is set, the next few dozen pages never have to think about it again.
Which Dozen to Lock First
| 组件 | 要定清楚什么 |
|---|---|
| 按钮 | 主要 / 次要 / 危险三种,每种含默认、悬停、按下、禁用、加载五个状态 |
| 输入框 | 默认、聚焦、报错、禁用、只读,加上标签和提示文字的位置 |
| 卡片 | 内边距、圆角、边框还是阴影,二选一别都用 |
| 列表项 | 行高、分隔方式、悬停态、选中态 |
| 标签 | 状态色一套,尺寸一到两种 |
| 弹窗 / 抽屉 | 宽度、标题区、内容区、按钮区的固定结构 |
| 空态 / 加载 / 错误 | 三个通用组件,全站复用(见四态齐全) |
| 提示条 | 成功、警告、错误三种,位置和消失时机统一 |
When you define them, write the exact values — not "slightly smaller radius." Values should be drawn from the spacing and type scale variables, not newly invented each time.
Note for the AI
## 组件 项目已有的组件在 src/components/ui/ 下。 做任何页面之前,先看一遍这个目录。 强制要求: - 需要按钮、输入框、卡片、列表项、标签、弹窗、 空态、加载态、错误态时,一律使用已有组件, 不要在页面里写内联样式或新建同类组件。 - 已有组件不满足需求时,先告诉我缺什么、 建议怎么扩展(加一个 variant 还是加一个 prop), 等我确认再改。不要绕过去自己写一个。 - 新建组件时,颜色 / 间距 / 字号 / 圆角必须引用设计变量, 不允许写死数值。 - 每个组件都要实现完整状态:按钮五态、输入框五态。 做完页面后,列出你用到的所有组件, 以及有没有新建或修改过任何组件。
That last line is a lightweight audit. It lets you catch the AI quietly inventing a new component, instead of finding out on page five that the style has drifted.
