Skip to content

refactor(frontend): 声明式配置表单组件 DynamicConfigForm + Form.Item 样板消除 - #129

Open
suantea wants to merge 1 commit into
PIKACHUIM:mainfrom
suantea:refactor/dynamic-config-form
Open

suantea wants to merge 1 commit into
PIKACHUIM:mainfrom
suantea:refactor/dynamic-config-form

Conversation

@suantea

@suantea suantea commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

背景

issue #124 PR-5。EasytierClient(172 个 Form.Item)、FrpClient(140 个)等页面里,大量 Form.Item 形如:

<Col span={12}>
  <Form.Item name="xxx" label="标题" extra={<span style={{fontSize:11}}>说明</span>}>
    <Input placeholder="..." style={{width:'100%'}} />
  </Form.Item>
</Col>

只是控件类型与文案不同,属于复制粘贴式样板。

变更

新增 `components/SectionTitle.tsx

该组件此前在 9 个页面各有一份逐字副本,仅缩进风格不同(两种变体各若干份)。本 PR 收敛为单一实现,样式与 UI 完全不变。

新增 components/ConfigFields.tsx

  • FieldRow — 按字段声明渲染栅格行,支持 text / password / textarea / number / select / switch / checkbox
  • CheckboxGrid — 布尔开关网格,对应 EasytierClient 中 22 处重复的 Col + valuePropName="checked" + marginBottom:4 结构
  • escape hatch — children 字段透传自定义内容,供 Form.List、条件渲染等无法声明式表达的字段使用;不强行抽象
  • when 字段支持 Form.useWatch 联动显隐

渲染结构与手写 JSX 完全一致(同样的 Row/Col/Form.Item 层级),UI 零变化。

迁移与去重

文件 变化
EasytierClient.tsx 1259 → 1078 行,6 个 Tab 的配置区改为声明式;日志级别选项提为 LOG_LEVEL_OPTIONS,消除 2 处 6 行重复
FrpClient.tsx 1211 → 1039 行,主配置与连接设置两 Tab 改为声明式;3 组 Select 选项提为模块常量
其余 7 个页面 替换为共享 SectionTitle

合计 +259 / -666,净减 407 行。两个目标文件合计 2470 → 2117 行(-14%)。

关于「各砍一半」预估的偏离

issue 原文预估两个文件各砍约一半。实际只减 14%,原因是:

带业务逻辑的字段不适合声明式化——包括 Form.List(端口转发规则、地址列表)、联动显隐、自定义 addonAfter(私钥生成按钮)、跨字段校验。强行把这些塞进 FieldSpec 会让声明变成「一半是对象、一半是 JSX」的更差形态,损害可读性。

按 issue「明确不做」中的「不追求固定百分比缩减指标,以删重复为准」处理,只迁移了真正同构的部分。

验收

  • tsc --noEmit 通过
  • npm run build 通过,产物 chunk 大小无异常
  • 构建产物已在 .gitignore 中,未纳入提交

EasytierClient.tsx 中 3 个未使用的 import(Divider / parseAddrStr / randomStr)为上游既有,--noUnusedLocals 下改动前后均报,未在本 PR 处理。

后续

ConfigFields 是纯展示组件,FieldSpec 可直接复用到 EasytierServer(132 个 Form.Item)、NpsServer(134 个)、FrpServer(82 个)。建议后续 PR 按同一模式推进。

背景:EasytierClient(172 个 Form.Item)、FrpClient(140 个)等页面中,
大量 Form.Item 是「<Col><Form.Item name label extra rules><Input/></Form.Item></Col>」
的复制粘贴,仅控件类型与文案不同。

新增两个共享组件:
- components/SectionTitle.tsx
  此前该组件在 9 个页面各有一份逐字副本(仅缩进风格不同),
  本次收敛为单一实现,样式与 UI 完全不变
- components/ConfigFields.tsx
  - FieldRow:按字段声明渲染栅格行,支持
    text/password/textarea/number/select/switch/checkbox
  - CheckboxGrid:布尔开关网格,对应 EasytierClient 中
    22 处重复的「Col + valuePropName=checked + marginBottom:4」结构
  - 保留 escape hatch:children 字段透传自定义内容,
    供 Form.List、条件渲染等无法声明式表达的字段使用
  - when 字段支持 Form.useWatch 联动显隐

迁移与去重:
- EasytierClient:1259 → 1078 行(-181),6 个 Tab 的配置区改为声明式;
  日志级别选项提为 LOG_LEVEL_OPTIONS,消除 2 处 6 行重复
- FrpClient:1211 → 1039 行(-172),主配置与连接设置两 Tab 改为声明式;
  连接协议/认证方式/日志级别选项提为模块常量
- 其余 7 个页面替换为共享 SectionTitle

合计:+259 / -666,净减 407 行。
EasytierClient + FrpClient 两个目标文件合计 2470 → 2117 行(-14%)。
未达 issue 中「各砍一半」的预估——因为带业务逻辑的字段
(Form.List、联动显隐、自定义 addonAfter)不适合声明式,强行抽象会
损害可读性。按 issue「以删重复为准,不追求固定百分比」处理。

验收:tsc --noEmit 通过;npm run build 通过,产物 chunk 大小无异常。

(issue PIKACHUIM#124 PR-5)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant