Cuando hacemos sistemas de gestión backend, a menudo nos encontramos con formas muy complejas:
- Hay demasiados elementos de formulario
- Mostrar diferentes elementos de formulario en varios tipos de formulario
- Ciertos elementos del formulario desactivan la validación bajo ciertas condiciones
- Cada elemento del formulario también tendrá otra lógica personalizada, como cuadros de entrada que pueden insertar variables de plantilla, mostrar la cantidad de caracteres de entrada, cargar y mostrar imágenes y texto enriquecido . . .
- En esta complicada situación, complete la verificación y envío del formulario.
- Puede ver ejemplos específicos: en el ejemplo se omiten muchas funciones triviales y solo se conserva el marco de formulario complejo general para demostrar la solución.
vue
Toda la visualización y ocultación de elementos del formulario, validación, adquisición de datos, envío, personalización y otra lógica se reúnen
- Según el tipo de formulario, utilice
v-if/v-show
para gestionar la visualización y ocultación de los elementos del formulario.- En la validación personalizada
elementui
, determine si el elemento del formulario se valida según el tipo de formulario.- Según el tipo de formulario, obtenga diferentes datos y envíelos a diferentes interfaces
- Toda otra lógica personalizada
vue
puede contener fácilmente 2000
líneasDe hecho, es fácil pensar en separar múltiples subformularios de tipos correspondientes según diferentes tipos de formularios . Pero todavía encontré muchos problemas en la práctica: verificación del formulario entre padres e hijos, obtención de datos enviados generales , etc., y resumí un conjunto de soluciones:
Todos los componentes secundarios deben contener dos métodos validate
y getData
para que los llame el componente principal.
validate
Se utiliza para verificar los elementos del formulario de sus propios componentes y devolver un objeto promise
.
vaildate ( ) {
// 返回`elementUI`表单验证的结果(为`promise`对象)
return this . $refs [ "ruleForm" ] . validate ( ) ;
} ,
getData
Proporcionar datos de componentes secundarios.
getData ( ) {
// 返回子组件的form
return this . ruleForm ;
} ,
Utilice el patrón de estrategia para almacenar y obtener ref
del subformulario (el método utilizado para obtener el subformulario) y la función de envío . Se omiten muchos juicios if-else
.
data: {
// type和ref名称的映射
typeRefMap : {
1 : "message" ,
2 : "mail" ,
3 : "apppush"
} ,
// type和提交函数的映射。不同类型,接口可能不同
typeSubmitMap : {
1 : data => alert ( `短信模板创建成功${ JSON . stringify ( data ) } ` ) ,
2 : data => alert ( `邮件模板创建成功${ JSON . stringify ( data ) } ` ) ,
3 : data => alert ( `push模板创建成功${ JSON . stringify ( data ) } ` )
} ,
}
submit
Se utiliza para la validación del formulario de componentes padre-hijo, la obtención de datos generales y la llamada a la función de envío de tipo actual para enviar datos.
Debido a que el método
validate
de la verificación del formularioelementUI
puede devolver un resultadopromise
, puede usar las características depromise
para manejar la verificación de los formularios principal e secundario. Por ejemplo, la funciónthen
puede devolver otro objetopromise
, ycatch
puede obtenerreject
yPromise.all
de todosthen
están encima de él.
// 父表单验证通过才会验证子表单,存在先后顺序
submitForm ( ) {
const templateType = this . typeRefMap [ this . indexForm . type ] ;
this . $refs [ "indexForm" ]
. validate ( )
. then ( res => {
// 父表单验证成功后,验证子表单
return this . $refs [ templateType ] . vaildate ( ) ;
} )
. then ( res => {
// 全部验证通过
// 获取整体数据
const reqData = {
// 获取子组件数据
... this . $refs [ templateType ] . getData ( ) ,
... this . indexForm
} ;
// 获取当前表单类型的提交函数,并提交
this . typeSubmitMap [ this . indexForm . type ] ( reqData ) ;
} )
. catch ( err => {
console . log ( err ) ;
} ) ;
} ,
submitForm1 ( ) {
const templateType = this . typeRefMap [ this . indexForm . type ] ;
const validate1 = this . $refs [ "indexForm" ] . validate ( ) ;
const validate2 = this . $refs [ templateType ] . vaildate ( ) ;
// 父子表单一起验证
Promise . all ( [ validate1 , validate2 ] )
. then ( res => {
// 都通过时,发送请求
const reqData = {
... this . $refs [ templateType ] . getData ( ) ,
... this . indexForm
} ;
this . typeSubmitMap [ this . indexForm . type ] ( reqData ) ;
} )
. catch ( err => {
console . log ( err ) ;
} ) ;
} ,
Resumen: Me he encontrado con este tipo de formularios complejos en muchos proyectos y he utilizado muchas soluciones. Aquí resumí una solución relativamente clara y simple. Por supuesto, hay muchas otras soluciones, por ejemplo , el método de envío de datos se puede colocar en cada subcomponente y los datos del elemento del formulario público se pasan al subcomponente a través de
props
para el envío . Si hay otras soluciones más simples, puede comentar o enviarissue
engithub
Fuera de tema: después de leer el propio relato del arquitecto front-end: la pregunta y respuesta de N sobre el camino de crecimiento de un ingeniero front-end, me inspiró mucho. Cuando está confundido acerca de su dirección técnica y sus perspectivas, o cuando se queja de que su proyecto es demasiado bajo, o cuando se queja de que está haciendo un trabajo repetitivo todos los días, o cuando se siente abrumado por la aparición interminable de nuevas tecnologías todos los días , También podrías echar un vistazo serio a tu proyecto .
A partir de los puntos débiles de los procesos de trabajo y proyectos , progresará más rápido en la práctica, el resumen y la resolución de problemas prácticos .
Mis sentimientos al escribir este artículo: la dificultad de expresar estas cosas
>>
la dificultad técnica contenida en el propio artículo