123 lines
3.7 KiB
Markdown
123 lines
3.7 KiB
Markdown
# 表单重构总结 - elder-form.uvue
|
||
|
||
## 重构前后对比
|
||
|
||
### 重构前的实现方式
|
||
- **每个输入字段都有独立的 `@input` 事件处理函数**
|
||
- 例如:`onNameInput`, `onIdCardInput`, `onPhoneInput` 等
|
||
- 共有 **11 个独立的输入事件处理函数**
|
||
- 代码冗余度高,维护困难
|
||
|
||
### 重构后的实现方式
|
||
- **使用 `<form>` 标签统一处理表单数据**
|
||
- 所有 input 和 textarea 元素都添加了 `name` 属性
|
||
- 使用 `@submit="onFormSubmit"` 统一处理表单提交
|
||
- 通过 `e.detail.value` 一次性获取所有表单数据
|
||
|
||
## 主要改进点
|
||
|
||
### 1. 模板结构优化
|
||
```vue
|
||
<!-- 重构前 -->
|
||
<input class="form-input" :value="formData.name" @input="onNameInput" placeholder="请输入老人姓名" />
|
||
|
||
<!-- 重构后 -->
|
||
<form @submit="onFormSubmit">
|
||
<input class="form-input" name="name" :value="formData.name" placeholder="请输入老人姓名" />
|
||
</form>
|
||
```
|
||
|
||
### 2. 事件处理简化
|
||
```javascript
|
||
// 重构前:需要 11 个独立函数
|
||
onNameInput(e: InputEvent) {
|
||
this.formData.name = e.detail.value
|
||
},
|
||
onIdCardInput(e: InputEvent) {
|
||
this.formData.id_card = e.detail.value
|
||
},
|
||
// ... 其余 9 个函数
|
||
|
||
// 重构后:统一处理
|
||
onFormSubmit(e: UniFormSubmitEvent) {
|
||
const formValues = e.detail.value as Map<string, any>
|
||
|
||
this.formData.name = formValues.get('name') || ''
|
||
this.formData.id_card = formValues.get('id_card') || ''
|
||
// ... 其余字段
|
||
|
||
this.submitForm()
|
||
}
|
||
```
|
||
|
||
### 3. 特殊控件处理
|
||
对于 `picker` 组件,由于它们不是标准的表单控件,采用了混合方式:
|
||
- 保留原有的 `@change` 事件处理
|
||
- 添加隐藏的 `input` 字段来同步数据到表单
|
||
```vue
|
||
<picker @change="onGenderChange">
|
||
<!-- picker 显示 -->
|
||
</picker>
|
||
<!-- 隐藏字段同步数据 -->
|
||
<input name="gender" type="text" :value="formData.gender" style="display: none;" />
|
||
```
|
||
|
||
### 4. 按钮类型优化
|
||
```vue
|
||
<!-- 重构前 -->
|
||
<button class="btn btn-cancel" @click="goBack">取消</button>
|
||
<button class="btn btn-submit" @click="submitForm">提交</button>
|
||
|
||
<!-- 重构后 -->
|
||
<button class="btn btn-cancel" type="button" @click="goBack">取消</button>
|
||
<button class="btn btn-submit" form-type="submit">提交</button>
|
||
```
|
||
|
||
## 优势分析
|
||
|
||
### 1. 代码简洁性
|
||
- **减少了 85% 的事件处理函数**(从 11 个减少到 1 个)
|
||
- 表单逻辑更集中,易于维护
|
||
|
||
### 2. 一致性
|
||
- 遵循 HTML 表单标准
|
||
- 与登录页面等其他页面保持一致的实现方式
|
||
|
||
### 3. 扩展性
|
||
- 添加新字段时只需添加 `name` 属性
|
||
- 无需编写额外的事件处理函数
|
||
|
||
### 4. 错误处理
|
||
- 统一的数据收集点,便于添加统一的验证和错误处理
|
||
- 更容易实现表单重置、数据回显等功能
|
||
|
||
## 技术要点
|
||
|
||
### 1. UTS 类型安全
|
||
```typescript
|
||
onFormSubmit(e: UniFormSubmitEvent) {
|
||
const formValues = e.detail.value as Map<string, any>
|
||
// 类型安全的数据获取
|
||
}
|
||
```
|
||
|
||
### 2. 数据同步策略
|
||
- **直接输入控件**:通过 `name` 属性和表单事件获取
|
||
- **Picker 控件**:通过事件更新 `formData`,隐藏字段同步到表单
|
||
- **上传控件**:通过事件更新 `formData`,隐藏字段同步到表单
|
||
|
||
### 3. 向后兼容
|
||
- 保持原有的数据结构不变
|
||
- 保持原有的业务逻辑不变
|
||
- 只优化了数据收集方式
|
||
|
||
## 最佳实践建议
|
||
|
||
1. **新表单应该默认使用 `<form>` 方式**
|
||
2. **为所有表单控件添加 `name` 属性**
|
||
3. **特殊控件(picker、upload)使用隐藏字段同步数据**
|
||
4. **取消按钮使用 `type="button"` 避免意外提交**
|
||
5. **提交按钮使用 `form-type="submit"` 触发表单事件**
|
||
|
||
这次重构大大提升了代码的可维护性和可读性,为后续的表单开发提供了更好的模式参考。
|