意图原型设计:利用AI构建清晰可交互原型的完整指南

本文详细介绍意图原型设计方法,通过AI辅助将设计草图直接转化为可交互原型。涵盖从概念模型生成到React应用构建的完整技术流程,包括Zustand状态管理、TypeScript类型定义和Ant Design组件使用。

意图原型设计:构建清晰原型的实践指南(第二部分)

在本系列的第一部分中,我们探讨了以模型为中心设计所产生的"不平衡马"问题,并展示了氛围编码的诱人承诺通常会导致结构缺陷。主要问题仍然是:

我们如何缩小设计意图与实时原型之间的差距,以便从第一天开始就能在真实功能上进行迭代,而不会陷入模糊性陷阱?

换句话说,我们需要一种方法来构建既快速创建又基于清晰、明确蓝图的原型。

答案是我称之为意图原型设计的更严谨过程。这种方法拥抱AI辅助编码的力量,但拒绝模糊性,将设计师的明确意图置于流程的核心位置。它接收意图的整体表达(屏幕布局草图、概念模型描述、用户流程的框图和箭头),并使用它来生成实时、可测试的原型。

意图原型设计工作流程

这种方法以最佳方式解决了我们在第一部分中讨论的担忧:

  • 与静态模型不同,原型完全可交互,并且可以轻松填充大量真实数据。这让我们能够测试系统的底层逻辑及其表面。
  • 与氛围编码原型不同,它是基于稳定、明确的规范构建的。这防止了概念模型失败和设计债务的发生。工程团队不需要对黑盒进行逆向工程或成为"代码考古学家"来猜测设计师的愿景,因为他们不仅接收实时原型,还接收其背后明确记录的设计意图。

这种组合使该方法特别适合设计复杂的企业应用程序。它允许我们以以前不可能的速度和灵活性测试系统最关键故障点——其底层结构。此外,该流程专为迭代而构建。您可以通过更改意图并根据从用户测试中学到的内容来演进设计,探索任意多个方向。

我的工作流程

为了说明这个流程的实际操作,让我们通过一个案例研究来了解。这正是我用来说明氛围编码陷阱的同一个例子:一个用于跟踪测试以验证产品想法的简单工具。您可以在GitHub存储库中找到完整的项目,包括下面讨论的所有源代码和文档文件。

步骤1:表达意图

想象我们已经做了适当的研究,并在思考定义的问题后,我开始形成解决方案可能是什么样子的模糊想法。我需要立即捕捉这个想法,所以我快速画出草图:

在这个例子中,我使用了Excalidraw,但工具并不重要。请注意,我们故意保持粗糙,因为视觉细节不是我们在这个阶段需要关注的内容。我们不会被困在这里:我们希望从这个初始草图直接跃升到可以放在潜在用户面前的实时原型。打磨这些草图不会让我们更接近实现目标。

我们需要向前推进的是向这些草图添加足够的细节,以便它们可以作为初级前端开发人员(或者在我们的案例中,是AI助手)的足够输入。这需要解释以下内容:

  • 导航路径(点击这里带你到)
  • 无法在静态图片中显示的交互细节(例如,不可滚动区域、自适应布局、拖放行为)
  • 哪些部分构建为可重用组件是有意义的
  • 应使用设计系统(我使用的是Ant Design Library)中的哪些组件
  • 任何其他有助于理解这个东西应该如何工作的评论(而草图说明它应该如何看)

添加所有这些细节后,我们最终得到这样一个带注释的草图:

如您所见,这个草图涵盖了可视化和流程两个方面。您可能会问,概念模型呢?没有这部分,我们的意图表达将不完整。一种方法是在草图的边缘添加它(例如,作为UML类图),在更复杂的应用程序中我会这样做,其中模型不能简单地从UI推导出来。但在我们的案例中,我们可以节省精力,并要求LLM基于草图生成概念模型的全面描述。

对于这类任务,我选择的LLM是Gemini 2.5 Pro。重要的是,这是一个多模态模型,不仅可以接受文本,还可以接受图像作为输入(GPT-5和Claude-4也符合这个标准)。我使用Google AI Studio,因为它给了我足够的控制和可见性:

结果,Gemini给了我们一个描述和以下图表:

该图表可能看起来技术性很强,但我相信对所有对象、它们的属性以及它们之间关系的清晰理解是良好设计的关键。这就是为什么我认为概念模型与流程和可视化一样,是表达意图的重要组成部分。

作为这一步的结果,我们的意图完全表达在两个文件中:Sketch.png和Model.md。这将是我们持久的真相来源。

步骤2:准备规范和计划

这一步的目的是创建全面的技术规范和逐步计划。这里的大部分工作由AI完成;您只需要关注它。

我分离数据访问层和UI层,并使用两个不同的提示为它们创建规范。第一个提示(数据访问层规范)的输出作为第二个提示的输入。请注意,作为额外输入,我们给出了针对原型设计需求定制的指南。它们不是特定于此项目的。这些指南中编码的技术方法超出了本文的范围。

结果,Gemini为我们提供了DAL.md和UI.md的内容。虽然在大多数情况下这个结果足够可靠,但您可能想要仔细检查输出。您不需要成为真正的程序员来理解它,但一定程度的编程素养会很有帮助。然而,即使您没有这样的技能,也不要气馁。好消息是,如果您不理解某些内容,您总是知道该问谁。在刷新上下文窗口之前,请在Google AI Studio中提问。如果您认为发现了问题,请告诉Gemini,它会修复它或解释为什么建议的方法实际上更好。

重要的是要记住,就其本质而言,LLMs不是确定性的,简单来说,可能会忘记小细节,特别是当涉及到草图中的细节时。幸运的是,您不需要成为专家就能注意到草图中右上角的"删除"按钮在规范中没有被提及。

不要误解:Gemini在大多数情况下表现出色,但有时仍然会出错。只需让它知道您发现的问题,一切都会得到修复。

一旦我们有了Sketch.png、Model.md、DAL.md、UI.md,并且我们已经审查了规范,我们可以喝杯咖啡。我们值得这样做:我们的技术设计文档完成了。它将作为构建实际事物的稳定基础,不会偏离我们最初的意图,并确保所有组件完美配合,所有层都正确堆叠。

在进入下一步之前,我们可以做的最后一件事是准备一个逐步计划。我们将该计划分为两部分:一部分用于数据访问层,另一部分用于UI。

步骤3:执行计划

要开始构建实际事物,我们需要切换到另一类AI工具。到目前为止,我们一直依赖生成式AI。它擅长基于单个提示创建新内容(在我们的案例中是规范和计划)。我使用Google AI Studio中的Google Gemini 2.5 Pro,但其他类似工具也可能适合这种一次性任务:ChatGPT、Claude、Grok和DeepSeek。

然而,在这一步,这还不够。基于规范并根据计划构建原型需要一个能够从多个文件读取上下文、执行一系列任务并保持连贯性的AI。简单的生成式AI无法做到这一点。这就像要求一个人通过只向他们展示一块砖来建造一座房子。我们需要的是一个代理AI,它可以获得完整的房屋蓝图和项目计划,然后开始按正确顺序建造地基、搭建墙壁和添加屋顶。

我选择的编码代理是Google Gemini CLI,仅仅因为Gemini 2.5 Pro对我很有效,而且我认为我们不需要任何中间人,如Cursor或Windsurf(它们无论如何都会在底层使用Claude、Gemini或GPT)。如果我使用Claude,我的选择会是Claude Code,但由于我坚持使用Gemini,所以就是Gemini CLI。但如果您更喜欢Cursor或Windsurf,我相信您可以使用您喜欢的工具应用相同的流程。

在分配代理任务之前,我们需要为我们的React应用程序创建一个基本模板。我不会在这里详细介绍。您可以找到大量关于如何使用Vite搭建空React项目的教程。

然后我们将所有文件放入该项目中:

一旦带有我们所有文件的基本模板准备就绪,我们打开终端,转到我们的项目所在的文件夹,然后输入"gemini":

然后我们发送提示来构建数据访问层。该提示意味着逐步执行,因此在完成每个步骤后,我发送以下内容:

1
2
3
Thank you! Now, please move to the next task.
Remember that you must not make assumptions based on common patterns; always verify them with the actual data from the spec. 
After each task, stop so that I can test it. Don't move to the next task before I tell you to do so.

作为计划中的最后一个任务,代理构建了一个特殊页面,我们可以在其中测试数据访问层的所有功能,以便我们可以手动测试它。它可能看起来像这样:

至少可以说,它看起来不花哨,但它允许我们在继续构建最终UI之前确保数据访问层正常工作。

最后,我们清除Gemini CLI上下文窗口以给它更多空间,并发送提示来构建UI。此提示也意味着逐步执行。在完成每个步骤后,我们按照UI-plan.md中的"手动测试计划"测试它的工作和外观。我不得不说,尽管草图已上传到模型上下文,并且总的来说Gemini试图遵循它,但对视觉细节的关注并不是它的强项(目前)。通常,在每个步骤都需要一些额外的推动来改善外观和感觉:

一旦我对一个步骤的结果满意,我就要求Gemini继续:

1
2
3
Thank you! Now, please move to the next task.
Make sure you build the UI according to the sketch; this is very important. Remember that you must not make assumptions based on common patterns; always verify them with the actual data from the spec and the sketch.  
After each task, stop so that I can test it. Don't move to the next task before I tell you to do so.

不久之后,结果看起来像这样,并且在每个细节上都完全按照我们的意图工作:

原型已启动并运行,看起来不错。这是否意味着我们的工作完成了?当然不是,最迷人的部分才刚刚开始。

步骤4:学习和迭代

是时候将原型放在潜在用户面前,并更多地了解这个解决方案是否能缓解他们的痛苦。

一旦我们学到新东西,我们就迭代。我们根据新的输入调整或扩展草图和概念模型,更新规范,创建根据新规范进行更改的计划,并执行这些计划。换句话说,对于每次迭代,我们重复刚刚带您完成的步骤。

这个工作流程是否太重?

这个四步工作流程可能会给人一种有些繁重的过程的印象,需要太多的前期思考,并且不能真正促进创造力。但在得出这个结论之前,请考虑以下因素:

  • 在实践中,只有第一步需要真正的努力,以及最后一步的学习。AI在中间做了大部分工作;您只需要关注它。
  • 单个迭代不需要很大。您可以从行走骨架开始:您心中所想事物的最低限度实现,并在后续迭代中添加更多实质内容。欢迎您在迭代之间改变整体方向。
  • 最后但同样重要的是,也许"三思而后行"的想法不是您需要逃避的。清晰明确的意图陈述可以防止许多不必要的错误,并在以后节省大量精力。

意图原型设计与其他方法

没有一种方法适合所有情况,意图原型设计也不例外。像任何专业工具一样,它有特定的目的。最有效的团队不是那些掌握单一方法的团队,而是那些了解在每个阶段使用哪种方法来减轻最重大风险的团队。下表让您更清楚地做出这个选择。它将意图原型设计与其他常见方法和工具放在一起,并根据它帮助实现的主要目标和它最适合减轻的特定风险来解释每种方法。

方法/工具 目标 最适合减轻的风险 例子 原因
意图原型设计 快速迭代具有复杂概念模型、复杂业务逻辑和非线性用户流程的数据密集型应用程序的基本架构 构建具有缺陷或不连贯概念模型的系统,导致严重错误和昂贵的重构 CRM(客户关系管理系统)、资源管理工具、无代码集成平台(管理员UI) 它强制执行概念清晰度。这不仅降低了核心结构的风险,还产生了一个清晰的、有文档记录的蓝图,作为工程交接的优越规范
氛围编码(对话式) 通过即兴创作快速探索交互式想法 因分析瘫痪而失去动力 具有实时排序/过滤功能的交互式数据表、新颖的导航概念、单个复杂组件的概念验证 它在自然语言传达的想法和交互结果之间具有最小的循环
Axure 测试特定用户旅程中的复杂条件逻辑,而不必担心整个系统如何工作 设计当用户不遵循"快乐路径"时会中断的流程 多步骤电子商务结账、软件配置向导、具有依赖字段的动态表单 它旨在创建复杂的if-then逻辑并可视化管理变量。这让您无需编写任何代码即可测试用户旅程中的复杂路径和边缘情况
Figma 确保用户界面看起来不错,符合品牌,并具有清晰的信息架构 制作外观糟糕、不符合品牌或布局难以理解的产品 营销落地页、用户引导流程、呈现新的视觉识别 它擅长高保真视觉设计,并为链接静态屏幕提供简单、快速的工具
ProtoPie, Framer 使高保真微交互感觉恰到好处 由于执行不佳的交互而发布感觉笨拙和不愉快的应用程序 自定义下拉刷新动画、流畅的拖放界面、动画图表或数据可视化 这些工具让您可以详细操作动画时间轴、物理效果和设备传感器输入。设计师可以仔细处理并测试使界面感觉真正精致和有趣使用的小细节
低代码/无代码工具(例如,Bubble, Retool) 尽可能快地创建工作的、数据驱动的应用程序 由于传统开发太昂贵,应用程序永远不会被构建 内部库存跟踪器、客户支持仪表板、简单的目录网站 它们将UI构建器、数据库和托管全部放在一个地方。目标不仅仅是制作一个想法的原型,而是制作和发布一个实际的、工作的产品。这是许多内部工具或MVP的最后一步

关键要点是,每种方法都是减轻特定类型风险的专业工具。例如,Figma降低了视觉呈现的风险。ProtoPie降低了交互感觉的风险。意图原型设计处于独特的位置,可以解决复杂应用程序中最基础的风险:构建在有缺陷或不连贯的概念模型上。

总结

“不平衡马"设计时代——表面光滑但结构不健全——是保真度和灵活性之间权衡的直接结果。这种权衡导致了一个充满冗余工作和错位焦点的过程。由现代AI驱动的意图原型设计消除了这种冲突。它不仅仅是构建更快的捷径——它是我们设计方式的根本转变。通过将清晰、明确的意图置于流程的核心,它让我们摆脱冗余工作,专注于构建健全和健壮的系统。

这种重新聚焦有三个主要好处。首先,通过直接进入实时、交互式原型,我们将验证工作从表面转移到深层,从第一天开始就用用户测试系统的实际逻辑。其次,记录设计意图的行为本身使我们的想法清晰,确保我们完全理解系统的底层逻辑。最后,这种记录的意图成为持久的真相来源,消除了模糊的交接和让工程师从黑盒中逆向工程设计设计师愿景的冗余、容易出错的工作。

最终,意图原型设计改变了我们工作的对象。它让我们超越创建产品图片,并使我们能够成为系统蓝图的设计师。在AI的帮助下,我们终于可以使实时原型成为构思的主要画布,而不仅仅是高投入的事后想法。

附录

您可以在GitHub存储库中找到完整的意图原型设计入门套件,其中包括所有这些提示和指南,以及本文中的示例和一个最小的样板项目。

附录1:从草图到UML类图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
您是一位专门研究领域驱动设计的专家级高级软件架构师。您的任务是基于UI草图的信息为应用程序定义概念模型

## 工作流程

请精确遵循以下步骤:

**步骤1** 仔细分析草图。关于我们正在构建什么应该没有歧义。

**步骤2** 使用UML类图以Mermaid格式生成概念模型描述

## 基本规则

- 每个实体必须具有以下属性:
    - `id` (字符串)
    - `createdAt` (字符串, ISO 8601格式)
    - `updatedAt` (字符串, ISO 8601格式)
- 包括UI中显示的所有属性:如果一段数据被可视化为实体的字段,请将其包含在模型中,即使它是从其他属性计算得出的。
- 不要添加任何推测性的实体、属性或关系("以防万一")。模型应仅满足当前草图的要求。
- 特别注意基数定义(例如,如果关系在两端都是可选的,则不能是`"1" -- "0..*"`,必须是`"0..1" -- "0..*"`)。
- Mermaid图中仅使用有效语法
- 不要在Mermaid图中包含枚举
- 添加注释解释每个实体、属性和关系的目的及其预期行为(不作为图表的一部分,在Markdown文件中)。

## 命名约定

- 名称应揭示意图和目的。
- 对实体名称使用PascalCase
- 对属性和关系使用camelCase
- 使用带有辅助动词的描述性变量名(例如,isLoadinghasError)。

## 最终指令

- **不作假设:** 基于草图中的视觉证据构建每个细节,而不是基于常见的设计模式。
- **双重检查:** 在撰写整个文档后,通读以确保层次结构逻辑合理,描述明确,格式一致。最终文档应是一个自包含的、全面的规范。
- **不要在项目之间添加冗余的空行。**

您的最终输出应该是`Model.md`的完整、原始markdown内容

附录2:从草图到DAL规范

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
您是一位专门研究ReactTypeScript和Zustand的专家级高级前端开发人员。您的任务是基于UI草图和概念模型描述为开发团队创建全面的技术规范,以结构化的markdown文档形式

## 工作流程

请精确遵循以下步骤:

**步骤1** 仔细分析文档:

- `Model.md`:概念模型
- `Sketch.png`UI草图

关于我们正在构建什么应该没有歧义。

**步骤2** 查看指南:

- `TS-guidelines.md`TypeScript最佳实践
- `React-guidelines.md`React最佳实践
- `Zustand-guidelines.md`Zustand最佳实践

**步骤3** 为存储和实体特定钩子创建Markdown规范,实现所有逻辑并提供所有必需的操作。

---

## Markdown输出结构

对整个文档使用此模板。

```markdown

# 数据访问层规范

本文档概述了应用程序数据访问层的规范,遵循`docs/guidelines/Zustand-guidelines.md`中定义的原则。

## 1. 类型定义

位置:`src/types/entities.ts`

### 1.1. `BaseEntity`

所有实体应扩展的共享接口。

[TypeScript接口定义]

### 1.2. `[实体名称]`

[实体名称]实体的接口。

[TypeScript接口定义]

## 2. Zustand存储

### 2.1. `[实体名称]`的存储

**位置:** `src/stores/[实体名称(复数)].ts`

Zustand存储将管理所有[实体名称]项目的状态。

**存储状态(`[实体名称]State`):**

[TypeScript接口定义]

**存储实现(`use[实体名称]Store`):**

- 存储将使用`create<[实体名称]State>()(...)`创建。
- 它将使用`zustand/middleware`中的`persist`中间件将状态保存到`localStorage`。持久化键将是`[实体存储键]`
- `[实体名称(复数,camelCase]`将是一个字典(`Record<string, [实体]>`),用于O(1)访问。

**操作:**

- **`add[实体名称]`**  
    [基于实体需求定义操作行为]
- **`update[实体名称]`**  
    [基于实体需求定义操作行为]
- **`remove[实体名称]`**  
    [基于实体需求定义操作行为]
- **`doSomethingElseWith[实体名称]`**  
    [基于实体需求定义操作行为]
    
## 3. 自定义钩子

### 3.1. `use[实体名称(复数)]`

**位置:** `src/hooks/use[实体名称(复数)].ts`

该钩子将是UI组件与[实体名称]数据交互的主要接口。

**钩子返回值:**

[TypeScript接口定义]

**钩子实现:**

[列出此钩子返回的所有属性和方法,并简要解释它们背后的逻辑,包括数据转换、记忆化。不要在这里写实际代码。]

最终指令

  • 不作假设: 基于概念模型或草图中的视觉证据构建规范中的每个细节,而不是基于常见的设计模式。
  • 双重检查: 在撰写整个文档后,通读以确保层次结构逻辑合理,描述明确,格式一致。最终文档应是一个自包含的、全面的规范。
  • 不要在项目之间添加冗余的空行。

您的最终输出应该是DAL.md的完整、原始markdown内容。

1
2

### 附录3:从草图到UI规范

您是一位专门研究React、TypeScript和Ant Design库的专家级高级前端开发人员。您的任务是通过将UI草图转换为结构化的markdown文档为开发团队创建全面的技术规范。

工作流程

请精确遵循以下步骤:

步骤1: 仔细分析文档:

  • Sketch.png:UI草图
    • 请注意,草图中的红线、红箭头和红文本是给您的注释,不应成为最终UI设计的一部分。它们提供提示和澄清。永远不要直接将它们转换为UI元素。
  • Model.md:概念模型
  • DAL.md:数据访问层规范

关于我们正在构建什么应该没有歧义。

步骤2: 查看指南:

  • TS-guidelines.md:TypeScript最佳实践
  • React-guidelines.md:React最佳实践

步骤3: 为新文件UI.md生成完整的markdown内容。


Markdown输出结构

对整个文档使用此模板。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# UI层规范

本文档指定了应用程序的UI层,根据提供的草图将其分解为页面和可重用组件。所有组件将遵循Ant Design的原则,并利用`docs/guidelines/Zustand-guidelines.md`中定义的数据访问模式。

## 1. 高级结构

该应用程序是一个单页面应用程序(SPA)。它将由一个主布局、一个主要页面和几个可重用组件组成。

### 1.1. `App`组件

设置路由和全局提供程序的根组件。

-   **位置**`src/App.tsx`
-   **目的**:提供全局上下文,包括Ant Design的`ConfigProvider`和用于消息通知的`App`上下文,并渲染主页面。
-   **组成**  -   使用来自'antd'的`ConfigProvider``App as AntApp`包装应用程序,以启用根据`simple-ice/antd-messages.mdc`的全局消息通知。
  -   渲染`[页面名称]`
## 2. 页面

### 2.1. `[页面名称]`

-   **位置:** `src/pages/PageName.tsx`
-   **目的:** [简要描述此页面的主要目标和功能]
-   **数据访问:**
  [列出此组件用于获取或管理其数据的特定钩子和函数]
-   **内部状态:**
    [描述使用`useState`由此页面内部管理的任何状态]
-   **组成:**
    [简要描述此页面的内容]
-   **用户交互:**
    [描述用户如何与此页面交互] 
-   **逻辑:**
  [如果适用,提供关于此页面应如何工作的额外注释]

## 3. 组件

### 3.1. `[组件名称]`

-   **位置:** `src/components/ComponentName.tsx`
-   **目的:** [解释此组件的作用以及在哪里使用]
-   **属性:**
  [组件属性的TypeScript接口定义。属性应最小化。通过使用钩子进行数据访问来避免属性钻取。]
-   **数据访问:**
    [列出此组件用于获取或管理其数据的特定钩子和函数]
-   **内部状态:**
    [描述使用`useState`由此组件内部管理的任何状态]
-   **组成:**
    [简要描述此组件的内容]
-   **用户交互:**
    [描述用户如何与此组件交互]
-   **逻辑:**
  [如果适用,提供关于此组件应如何工作的额外注释]
  

最终指令

  • 不作假设: 基于草图中的视觉证据构建每个细节,而不是基于常见的设计模式。
  • 双重检查: 在撰写整个文档后,通读以确保层次结构逻辑合理,描述明确,格式一致。最终文档应是一个自包含的、全面的规范。
  • 不要在项目之间添加冗余的空行。

您的最终输出应该是UI.md的完整、原始markdown内容。

1
2

### 附录4:从DAL规范到计划

您是一位专门研究React、TypeScript和Zustand的专家级高级前端开发人员。您的任务是基于规范为应用程序创建构建数据访问层的计划。

工作流程

请精确遵循以下步骤:

步骤1: 仔细分析文档:

  • DAL.md:应用程序数据访问层的完整技术规范。请仔细并严格按照它执行。

关于我们正在构建什么应该没有歧义。

步骤2: 查看指南:

  • TS-guidelines.md:TypeScript最佳实践
  • React-guidelines.md:React最佳实践
  • Zustand-guidelines.md:Zustand最佳实践

步骤3: 创建根据规范构建数据访问层的逐步计划。

每个任务应:

  • 关注一个关注点
  • 合理小
  • 有明确的开始+结束
  • 包含明确定义的目标和验收标准

计划的最后一步应包括创建一个页面来测试我们数据访问层的所有功能,并将其设为此应用程序的起始页面,以便我可以手动检查它是否正常工作。

我将把这个计划交给一个工程LLM,它将被告知一次完成一个任务,允许我在中间审查结果。

最终指令

  • 请注意,我们不是从零开始;已经使用Vite创建了基本模板。
  • 不要在项目之间添加冗余的空行。

您的最终输出应该是DAL-plan.md的完整、原始markdown内容。

1
2

### 附录5:从UI规范到计划

您是一位专门研究React、TypeScript和Ant Design库的专家级高级前端开发人员。您的任务是基于规范和草图为应用程序创建构建UI层的计划。

工作流程

请精确遵循以下步骤:

步骤1: 仔细分析文档:

  • UI.md:应用程序UI层的完整技术规范。请仔细并严格按照它执行。
  • Sketch.png:包含有关布局和样式的重要信息,补充UI层规范。最终UI必须尽可能接近此草图。

关于我们正在构建什么应该没有歧义。

步骤2: 查看指南:

  • TS-guidelines.md:TypeScript最佳实践
  • React-guidelines.md:React最佳实践

步骤3: 创建根据规范和草图构建UI层的逐步计划。

每个任务必须:

  • 关注一个关注点。
  • 合理小。
  • 有明确的开始+结束。
  • 导致应用程序的可验证增量。每个增量应可手动测试,以便在继续之前进行功能审查和批准。
  • 包含明确定义的目标、验收标准和手动测试计划。

我将把这个计划交给一个工程LLM,它将被告知一次完成一个任务,允许我在中间进行测试。

最终指令

  • 请注意,我们不是从零开始,已经使用Vite创建了基本模板,并且数据访问层已成功构建。
  • 对于每个任务,描述应如何集成组件以进行验证。您必须使用提供的钩子连接到实时Zustand存储数据——不要使用模拟数据(请注意,数据访问层已经成功构建)。
  • 手动测试计划应读起来像用户指南。它必须仅包含用户可以在浏览器中执行的操作,并且绝不能引用任何代码文件或编程任务。
  • 不要在项目之间添加冗余的空行。

您的最终输出应该是UI-plan.md的完整、原始markdown内容。

1
2

### 附录6:从DAL计划到代码

您是一位专门研究React、TypeScript和Zustand的专家级高级前端开发人员。您的任务是基于规范为应用程序构建数据访问层。

工作流程

请精确遵循以下步骤:

步骤1: 仔细分析文档:

  • @docs/specs/DAL.md:应用程序数据访问层的完整技术规范。请仔细并严格按照它执行。

关于我们正在构建什么应该没有歧义。

步骤2: 查看指南:

  • @docs/guidelines/TS-guidelines.md:TypeScript最佳实践
  • @docs/guidelines/React-guidelines.md:React最佳实践
  • @docs/guidelines/Zustand-guidelines.md:Zustand最佳实践

步骤3: 阅读计划:

  • @docs/plans/DAL-plan.md:构建应用程序数据访问层的逐步计划。

步骤4: 根据规范和遵循计划为此应用程序构建数据访问层。

  • 一次完成计划中的一个任务。
  • 在每个任务之后,停止,以便我可以测试它。在我告诉您继续之前,不要移动到下一个任务。
  • 不要做任何其他事情。此时,我们专注于构建数据访问层。

最终指令

  • 不要基于常见模式做出假设;始终使用来自规范和草图的实际数据验证它们。
  • 不要启动开发服务器,我会自己启动。
1
2

### 附录7:从UI计划到代码

您是一位专门研究React、TypeScript和Ant Design库的专家级高级前端开发人员。您的任务是基于规范和草图为应用程序构建UI层。

工作流程

请精确遵循以下步骤:

步骤1: 仔细分析文档:

  • @docs/specs/UI.md:应用程序UI层的完整技术规范。请仔细并严格按照它执行。
  • @docs/intent/Sketch.png:包含有关布局和样式的重要信息,补充UI层规范。最终UI必须尽可能接近此草图。
  • @docs/specs/DAL.md:应用程序数据访问层的完整技术规范。该层已经准备就绪。使用此规范了解如何使用它。

关于我们正在构建什么应该没有歧义。

步骤2: 查看指南:

  • @docs/guidelines/TS-guidelines.md:TypeScript最佳实践
  • @docs/guidelines/React-guidelines.md:React最佳实践

步骤3: 阅读计划:

  • @docs/plans/UI-plan.md:构建应用程序UI层的逐步计划。

步骤4: 根据规范和草图,遵循逐步计划为此应用程序构建UI层:

  • 一次完成计划中的一个任务。
  • 确保您根据草图构建UI;这非常重要。
  • 在每个任务之后,停止,以便我可以测试它。在我告诉您继续之前,不要移动到下一个任务。

最终指令

  • 不要基于常见模式做出假设;始终使用来自规范和草图的实际数据验证它们。
  • 遵循Ant Design的默认样式和组件。
  • 不要触及数据访问层:它已经准备就绪并且是完美的。
  • 不要启动开发服务器,我会自己启动。
1
2

### 附录8:TS-guidelines.md

指南:TypeScript最佳实践

类型系统和类型安全

  • 对所有代码使用TypeScript并启用严格模式。
  • 确保存储、钩子和组件接口的完全类型安全。
  • 对于对象定义,优先使用接口而不是类型;对于联合、交集和映射类型,使用类型。
  • 实体接口应在扩展常见模式的同时保持其特定属性。
  • 在过滤操作中使用TypeScript类型守卫以确保关系安全。
  • 避免使用’any’类型;必要时优先使用’unknown’。
  • 使用泛型创建可重用的组件和函数。
  • 利用TypeScript的特性来强制执行类型安全。
  • 当导入类型时,使用仅类型导入(import type { MyType } from ‘./types’),因为启用了verbatimModuleSyntax。
  • 避免枚举;改用映射。

命名约定

  • 名称应揭示意图和目的。
  • 对组件名称和类型/接口使用PascalCase。
  • 对React属性使用’Props’前缀接口(例如,ButtonProps)。
  • 对变量和函数使用camelCase。
  • 对常量使用UPPER_CASE。
  • 对目录使用小写带破折号,对带有组件的文件使用PascalCase(例如,components/auth-wizard/AuthForm.tsx)。
  • 使用带有辅助动词的描述性变量名(例如,isLoading,hasError)。
  • 优先使用命名导出用于组件。

代码结构和模式

  • 编写简洁、技术性的TypeScript代码,并带有准确的示例。
  • 使用函数式和声明式编程模式;避免类。
  • 优先使用迭代和模块化,而不是代码重复。
  • 对纯函数使用"function"关键字。
  • 对所有条件语句使用花括号,以保持一致性和清晰度。
  • 根据其目的适当组织文件。
  • 将相关代码保持在一起并封装实现细节。

性能和错误处理

  • 使用不可变和高效的数据结构和算法。
  • 为领域特定错误创建自定义错误类型。
  • 使用带有类型捕获子句的try-catch块。
  • 正确处理Promise拒绝和异步错误。
  • 适当记录错误并优雅地处理边缘情况。

项目组织

  • 将共享类型放在types目录中。
  • 使用桶导出(index.ts)来组织导出。
  • 根据其目的构建文件和目录结构。

其他规则

  • 使用注释解释复杂逻辑或非显而易见的决策。
  • 遵循单一职责原则:每个函数应只做一件事。
  • 遵循DRY(不要重复自己)原则。
  • 不要实现占位函数、空方法或"以防万一"的逻辑。代码应仅满足当前规范的要求。
  • 使用2个空格进行缩进(无制表符)。
1
2

### 附录9:React-guidelines.md

指南:React最佳实践

组件结构

  • 使用函数式组件而不是类组件
  • 保持组件小而专注
  • 将可重用逻辑提取到自定义钩子中
  • 使用组合而不是继承
  • 使用TypeScript实现适当的属性类型
  • 构建React文件结构:导出的组件、子组件、辅助函数、静态内容、类型
  • 对React组件使用声明式TSX
  • 确保UI组件使用自定义钩子进行数据获取和操作,而不是通过属性接收数据,除了最简单的组件

React模式

  • 利用useState和useEffect钩子进行状态和副作用处理
  • 需要时使用React.memo进行性能优化
  • 利用React.lazy和Suspense进行代码分割
  • 实现错误边界以进行健壮的错误处理
  • 保持样式靠近组件

React性能

  • 避免不必要的重新渲染
  • 可能时懒加载组件和图像
  • 实现高效的状态管理
  • 优化渲染策略
  • 优化网络请求
  • 采用记忆化技术(例如,React.memo,useMemo,useCallback)

React项目结构

1
2
3
4
5
6
7
8
/src
- /components - UI组件(每个组件在单独的文件中)
- /hooks - 面向公众的自定义钩子(每个钩子在单独的文件中)
- /providers - React上下文提供者(每个提供者在单独的文件中)
- /pages - 页面组件(每个页面在单独的文件中)
- /stores - 实体特定的Zustand存储(每个存储在单独的文件中)
- /styles - 全局样式(如果需要)
- /types - 共享的TypeScript类型和接口
1
2

### 附录10:Zustand-guidelines.md

指南:Zustand最佳实践

核心原则

  • 为此React应用程序实现数据层,仔细并严格按照此规范执行。
  • 完全分离关注点:所有数据操作应通过简单干净的实体特定钩子在UI组件中可访问,确保状态管理逻辑与UI逻辑完全分离。
  • 共享状态架构:不同的UI组件应使用相同的共享状态,尽管分别使用实体特定钩子。

技术栈

  • 状态管理:使用Zustand进行状态管理,通过persist中间件实现自动localStorage持久化。

存储架构

  • 基础实体: 实现一个BaseEntity接口,具有所有实体扩展的公共属性:
1
2
3
4
5
export interface BaseEntity { 
  id: string; 
  createdAt: string; // ISO 8601格式 
  updatedAt: string; // ISO 8601格式 
}
  • 实体特定存储:为每种实体类型创建单独的Zustand存储。
  • 基于字典的存储:使用字典/映射结构(Record)而不是数组,以便通过ID进行O(1)访问。
  • 处理关系:在适当的情况下在存储中实现跨实体关系(如级联删除)。

钩子层

钩子层是UI组件和Zustand存储之间的专属接口。它设计简单、可预测,并在所有实体中遵循一致的模式。

核心原则

  1. 每个实体一个钩子:每个实体将有一个单一的、全面的自定义钩子(例如,useBlogPostsuseCategories)。此钩子是所有与该实体相关的数据和操作的唯一入口点。不会为单项目访问创建单独的钩子。
  2. 返回响应式数据,而不是获取函数:为防止过时数据,钩子必须返回状态本身,而不是检索状态的函数。参数化钩子以接受过滤器并直接返回派生数据。调用获取函数的组件在底层数据更改时将不会更新。
  3. 暴露字典以进行O(1)访问:为提供简单直接的数据访问,每个钩子将返回相关项目的字典(Record)。

标准钩

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计