在前端开发中,每个组件外面都套一层 el-form
(Element UI 的表单组件)并不是一个推荐的做法。这种做法可能会带来一些问题,尤其是在复杂项目中。以下是对这种做法的分析和建议:
1. 为什么会有这种想法?
- 表单验证需求:可能希望在每个组件中实现独立的表单验证。
- 统一管理 :希望通过
el-form
统一管理表单数据和校验规则。 - 快速开发:可能认为这样可以快速实现表单功能。
2. 这种做法的潜在问题
(1)性能问题
- 多余的 DOM 结构 :每个组件都嵌套一个
el-form
,会导致 DOM 层级过深,增加渲染负担。 - 额外的校验开销 :每个
el-form
都会初始化自己的校验逻辑,增加内存和计算开销。
(2)代码冗余
- 重复代码 :每个组件都包含
el-form
的模板和逻辑,导致代码冗余。 - 维护困难:如果需要修改表单逻辑,需要在多个地方同步修改,增加维护成本。
(3)表单逻辑分散
- 数据分散 :表单数据分散在各个组件的
el-form
中,难以集中管理。 - 校验逻辑分散:校验规则分散在各个组件中,难以统一处理。
(4)用户体验问题
- 不一致的校验行为 :每个
el-form
独立校验,可能导致用户需要多次提交才能发现所有错误。 - 复杂的交互逻辑 :多个
el-form
之间的联动和通信可能变得复杂。
3. 更好的实践方式
(1)单一表单容器
- 在父组件中使用一个
el-form
作为表单容器,统一管理表单数据和校验规则。 - 子组件通过
props
接收表单数据和校验规则,通过events
或v-model
更新数据。
(2)集中管理表单数据
- 使用 Vuex 或 Pinia 等状态管理工具,集中管理表单数据。
- 在父组件中统一处理表单提交和校验。
(3)动态表单校验
-
使用
el-form
的动态校验功能,根据组件状态动态添加或移除校验规则。 -
示例:
vue<el-form :model="formData" :rules="formRules" ref="form"> <el-form-item label="用户名" prop="username"> <el-input v-model="formData.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input v-model="formData.password" type="password"></el-input> </el-form-item> </el-form>
(4)组件解耦
-
将表单逻辑和 UI 组件解耦,使组件更专注于展示和交互。
-
示例:
vue<template> <el-form :model="formData" :rules="formRules" ref="form"> <user-info v-model="formData.userInfo" :rules="formRules.userInfo"></user-info> <address-info v-model="formData.addressInfo" :rules="formRules.addressInfo"></address-info> </el-form> </template> <script> export default { data() { return { formData: { userInfo: {}, addressInfo: {}, }, formRules: { userInfo: { /* 校验规则 */ }, addressInfo: { /* 校验规则 */ }, }, }; }, }; </script>
4. 适用场景
虽然不推荐每个组件都嵌套 el-form
,但在某些特定场景下,这种设计可能是合理的:
- 独立的功能模块:如果每个组件是一个完全独立的功能模块,且需要独立的表单校验。
- 复杂的动态表单:如果表单结构非常复杂,且需要动态生成表单字段。
5. 小结
- 不推荐 在每个组件外面都套一层
el-form
,这会导致性能问题、代码冗余和维护困难。 - 推荐 在父组件中使用一个
el-form
统一管理表单数据和校验规则,子组件通过props
和events
与父组件通信。 - 根据实际需求选择合适的表单设计方式,确保代码的可维护性和性能。
通过合理的表单设计,可以提高代码的可读性、可维护性和性能,同时提供更好的用户体验。
深入思考:
以前的业务框架设计我是每个组件外面包了一层 form,用来处理校验、参数收集等等,自成一体。如果新增组件,按照已有规则新增即可,不跟老代码有任何耦合,基本实现可插拔。今天想了一下有没有提升空间,把所有组件私有的都用接口实现配置化。
页面字段动态配置设计
不再给每个控件套一层form,还要满足新开发的组件不会干涉到老代码,就要把组件私有的东西做到配置化
字段组件
开发一套组件跟配置一一对应,确保业务字段配置页面配置的组件可以正常加载到
业务字段配置
- 给每个模块页面配置字段
- 后端实现crud
- 前端页面整体分两步,比方说修改页面:先调用页面的字段配置渲染页面的字段组件,再获取页面的字段值,填入到字段组件里。