如何制定前端组件协议

你只需要理解并清晰地描述需求,剩下的工作就交给 AI。

最近需要开发一个前端组件协议,根据历史经验,协议的制定是非常关键的,一旦设计得不合理,就会埋下巨大的隐患,影响后续组件的可扩展性和可维护性。因此以往这个环节的工作都是比较头疼的,且都由相对资深的开发人员来完成,且制定了也会很慌,总是担心考虑不够周到。

但是现在有了 AI 的帮助,这个环节的工作可以大大简化。AI 可以根据已有的需求描述,快速生成初步协议,并且可以根据讨论结果进行修改和优化。

以下是本次基于 AI 协助,制定协议的过程记录,供后续项目开发参考。

确定初步协议(AI)

其实这次的初步协议还是由开发人员制定的,当然他在这个过程中应该也借助了部分 AI 的帮助。

下次我们应该提供需求描述,直接让 AI 来确定初步协议,类似这样:

生成需求文档

我们只需提供一个粗糙的需求描述,让 AI 采用 EARS 规范帮我们生成详细的需求文档。

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
# 需求分析阶段 - Requirements Generation

我需要你帮我为一个 Web 应用项目生成详细的需求文档。项目描述详见:[项目描述]

请严格按照以下要求生成 requirements.md 文档:

## 文档结构要求:

1. **项目概述** - 简洁描述项目的核心价值和目标用户
2. **功能需求** - 使用 EARS 语法和用户故事格式
3. **非功能需求** - 性能、安全、可用性等要求
4. **约束条件** - 技术栈、时间、资源限制

## 格式规范:

### 用户故事格式:

- As a [角色], I want [功能], so that [价值/目的]

### 验收标准格式(EARS 语法):

- WHEN [触发条件] THEN the system SHALL [系统响应]
- IF [条件] THEN the system SHALL [行为]
- WHERE [状态] the system SHALL [行为]

## 输出要求:

1. 生成初始版本的需求文档
2. 考虑边界情况、用户体验、技术约束
3. 每个功能需求包含:用户故事 + 详细的验收标准列表
4. 使用层次化编号结构组织内容

## 项目描述

我想开发一个前端 UI 组件库,这个组件库会提供给其他的业务方使用。 组件库分为原子组件和组合组件。 原子组件是一些不能再拆分的细粒度的组件,比如说一个折线图,一个柱状图,一段文本,一个图标等等。
而组合组件则是由多个原子组件组合而成的。 比如像一段文本、柄图,和一个折线图的组合。 这个组件需要插入到业务方的原始网页中,因此需要考虑到样式污染隔离等问题。 我准备采用 Web Component 的方式进行开发。
我计划采用 UNO CSS 进行开发,因为它能保证打包到 Shadow DOM 中的 CSS 内容尽量少。
另外,这个组件后续供业务方使用时,可能会考虑在外层进行封装,比如封装成 React 或 Vue 框架,以进一步降低业务方的使用成本。

为了让这个组件库具备很强的扩展性和个性化定制能力,我感觉在组件库的协议制定上需要考虑得足够全面。 如下是我想到的一些需要关注的因素,在制定协议的时候可供参考:
2、需要制定原子组件和组合组件的 2 套协议
3、需要考虑组合组件内部的各个原子组件的联动交互
4、需要考虑个性化需求,分为两部分:
4.1 固定的通用个性化需求,比如业务风格(AInvest、手炒、黑白风格等)
4.2 原子组件独有的配置,每个原子组件不一样,需单独设计,比如 StandardChart 的配置项(类似预设 style 属性,透穿用户个性化配置到组件内部)
5、组件的协议类似页面 DSL 的形式,包含容器化设计,由容器消化掉通信等非渲染需求
6、组件的协议需要有容器的概念,容器内部包含各个更细粒度的组件,可以支持无限嵌套。 就类似于 DSL 一样,其实本身组合组件就类似于一个页面,有不同的元素构成。

请现在开始生成 requirements.md 的内容,生成后询问我是否需要修改或补充。

制定初步协议

1
请基于上一步生成的需求文档的内容,帮我制定组件的协议,并编写一个示例协议的 json 文件。

由人制定的协议示例

附上本次由开发人员制定的协议,因为这次是基于这个协议进行讨论的:

点击展开/收起
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
{
"type": "viz-card",
"display": "block",
"layout": "dashboard",
"components": [
{
"id": "card_title",
"type": "viz-text",
"slot": "header",
"content": "市场收益分析报告",
"style": {
"font_size": "24px",
"font_weight": "bold",
"color": "#1f2937",
"text_align": "center"
}
},
{
"id": "main_chart",
"type": "viz-chart",
"slot": "main",
"chart_type": "line",
"config": {
"width": "100%",
"height": "300px"
},
"data": {
"columns": [
{"key": "date", "type": "date", "label": "日期"},
{"key": "return", "type": "number", "label": "收益率", "format": "percentage"}
],
"records": [
{"date": "2024-01", "return": 0.08},
{"date": "2024-02", "return": 0.12},
{"date": "2024-03", "return": 0.15},
{"date": "2024-04", "return": 0.11},
{"date": "2024-05", "return": 0.18}
]
},
chart_spec: {
dataset: [{values: [...]}],
view: {
main: {
layers: [
{type: "line", encode: {x: "date", y: "return"} }
]
}
}
}
},
{
"id": "data_source",
"type": "viz-text",
"slot": "footer-left",
"content": "数据来源:Wind金融终端",
"style": {
"font_size": "12px",
"color": "#6b7280"
}
},
{
"id": "brand_logo",
"type": "viz-badge",
"slot": "footer-right",
"content": "AI Invest",
"style": {
"background": "#3b82f6",
"color": "white",
"border_radius": "6px",
"padding": "4px 8px",
"font_size": "12px"
}
}
],
"style": {
"card_padding": "20px",
"border_radius": "12px",
"background": "#ffffff",
"border": "1px solid #e5e7eb"
}
}

讨论和修改协议(人)

这一步由开发人员参与,这次是我和制定组件的同事一起讨论,根据实际需求,确定协议的修改细节,花费了 40 分钟。
最终产出如下的调整信息:

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
## 最外层属性

type 为可选属性,可不用加,默认就是 card
type 去掉 viz-前缀
"layout": 可缺省,如果后端没传递,就前端根据 components 的数量和每个 component 的 type 自动选择布局
LLM 需传递每个 component 的语义/业务信息,LLM 尽量不涉及表现层信息(除了风格需求)
容器增加 theme 字段,表示固定的通用个性化需求,比如业务风格(AInvest、手炒、黑白风格等)

## Component 属性

id 是 UUID
slot 根据外层是否传递 layout 来确定是否启用
data 用于存放纯数据
增加一个 attribute,用于存放组件私有属性,包括数据和行为(组件私有属性都放 attribute 下,便于扩展;component 的根属性都是通用属性)
style 用于存放组件样式相关的配置
content 放在 attribute 内部
属性命名改为驼峰命名,符合规范
chart_spec 放到 attribute 里面
增加 category 属性,用于在 type 下细分子类别,比如文本,可能分为 title、subtitle、caption、note、source
不用 brand_logo,组件库初始化的时候配置即可,默认都加上

## 和业务方对接的协议(这是扩展讨论的内容,和组件协议关系不大):

1、初始化组件的方式、需要传入的参数等
2、hover/click 的卡片定位谁来做?需要考虑边界情况
3、容器、组件、布局都需要支持 resize、destroy 等常用方法和生命周期钩子(组件的 Abstract Class 设计的时候先定好这些,实现可以靠后)

修改协议(AI)

接下来让 AI 根据讨论的结果,修改示例,这样可以快速生成一个新的协议版本,避免低效的人工修改。

1
2
3
4
5
6
7
这是我设计的一个初始的组件协议示例:
<补上初始协议的示例>

这是我们讨论后需要做出的调整:
<补上讨论的结果>

请根据讨论的结果,帮我修改这个示例 json,并写入本地 json 文件。

审核和优化协议(AI)

让 AI 进行审核,判断是否合理,是否存在可优化改进的空间:

1
2
3
4
5
6
7
8
9
10
请帮我审核一下,这个 json 中的协议是否合适?是否存在可以优化改进的地方?
包括:

- 需求场景的适配性
- 层级结构的合理性
- 命名的规范性与可理解性
- 组件的可扩展性
- 组件的可维护性
- 组件的可复用性
- ......

这一步会给出修改建议并生成新的示例。

确认最终协议(人)

由开发人员根据 AI 的审核结果,确认最终协议:

1