<script> export default { data() { var checkAge = (rule, value, callback) => { if (!value) { return callback(new Error('Please input the age')); } setTimeout(() => { if (!Number.isInteger(value)) { callback(new Error('Please input digits')); } else { if (value < 18) { callback(new Error('Age must be greater than 18')); } else { callback(); } } }, 1000); }; var validatePass = (rule, value, callback) => { if (value === '') { callback(new Error('Please input the password')); } else { if (this.ruleForm2.checkPass !== '') { this.$refs.ruleForm2.validateField('checkPass'); } callback(); } }; var validatePass2 = (rule, value, callback) => { if (value === '') { callback(new Error('Please input the password again')); } else if (value !== this.ruleForm2.pass) { callback(new Error('Two inputs don\'t match!')); } else { callback(); } }; return { form: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, sizeForm: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, formInline: { user: '', region: '' }, labelPosition: 'right', formLabelAlign: { name: '', region: '', type: '' }, ruleForm: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, ruleForm2: { pass: '', checkPass: '', age: '' }, formLabelWidth: '80px', options: [ ], rules: { name: [ { required: true, message: 'Please input Activity name', trigger: 'blur' }, { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' } ], region: [ { required: true, message: 'Please select Activity zone', trigger: 'change' } ], date1: [ { type: 'date', required: true, message: 'Please pick a date', trigger: 'change' } ], date2: [ { type: 'date', required: true, message: 'Please pick a time', trigger: 'change' } ], type: [ { type: 'array', required: true, message: 'Please select at least one activity type', trigger: 'change' } ], resource: [ { required: true, message: 'Please select activity resource', trigger: 'change' } ], desc: [ { required: true, message: 'Please input activity form', trigger: 'blur' } ] }, rules2: { pass: [ { validator: validatePass, trigger: 'blur' } ], checkPass: [ { validator: validatePass2, trigger: 'blur' } ], age: [ { validator: checkAge, trigger: 'blur' } ] }, dynamicValidateForm: { domains: [{ key: Date.now(), value: '' }], email: '' }, numberValidateForm: { age: '' } }; }, methods: { onSubmit() { console.log('submit!'); }, onRuleFormSubmit() { console.log('onRuleFormSubmit'); }, submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); }, removeDomain(item) { var index = this.dynamicValidateForm.domains.indexOf(item) if (index !== -1) { this.dynamicValidateForm.domains.splice(index, 1) } }, addDomain() { this.dynamicValidateForm.domains.push({ key: Date.now(), value: '' }); } } } </script> <style> .demo-form.demo-es { .el-select .el-input { width: 360px; } .el-form { width: 480px; } .line { text-align: center; } .el-checkbox-group { width: 320px; margin: 0; padding: 0; list-style: none; &:after, &:before { content: ' '; display: table; } &:after { clear: both; visibility: hidden; font-size: 0; height: 0; } .el-checkbox { float: left; width: 160px; padding-right: 20px; margin: 0; padding: 0; + .el-checkbox { margin-left: 0; } } } .demo-form-normal { width: 480px; } .demo-form-inline { width: auto; .el-input { width: 150px; } > * { margin-right: 10px; } } .demo-ruleForm { width: 480px; .el-select .el-input { width: 360px; } } .demo-dynamic { width: 500px; .el-input { margin-right: 10px; width: 270px; vertical-align: top; } } .fr { float: right; } } </style> ## Form Form consiste en `input`, `radio`, `select`, `checkbox`, etcétera. Con el formulario, usted puede recopilar, verificar y enviar datos. ### Form básico Incluye todo tipo de entradas, tales como `input`, `select`, `radio` y `checkbox`. :::demo En cada componente `form`, necesita un campo `form-item` para que sea el contenedor del item. ```html <el-form ref="form" :model="form" label-width="120px"> <el-form-item label="Activity name"> <el-input v-model="form.name"></el-input> </el-form-item> <el-form-item label="Activity zone"> <el-select v-model="form.region" placeholder="please select your zone"> <el-option label="Zone one" value="shanghai"></el-option> <el-option label="Zone two" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="Activity time"> <el-col :span="11"> <el-date-picker type="date" placeholder="Pick a date" v-model="form.date1" style="width: 100%;"></el-date-picker> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-time-picker type="fixed-time" placeholder="Pick a time" v-model="form.date2" style="width: 100%;"></el-time-picker> </el-col> </el-form-item> <el-form-item label="Instant delivery"> <el-switch v-model="form.delivery"></el-switch> </el-form-item> <el-form-item label="Activity type"> <el-checkbox-group v-model="form.type"> <el-checkbox label="Online activities" name="type"></el-checkbox> <el-checkbox label="Promotion activities" name="type"></el-checkbox> <el-checkbox label="Offline activities" name="type"></el-checkbox> <el-checkbox label="Simple brand exposure" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="Resources"> <el-radio-group v-model="form.resource"> <el-radio label="Sponsor"></el-radio> <el-radio label="Venue"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="Activity form"> <el-input type="textarea" v-model="form.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">Create</el-button> <el-button>Cancel</el-button> </el-form-item> </el-form> <script> export default { data() { return { form: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' } } }, methods: { onSubmit() { console.log('submit!'); } } } </script> ``` ::: :::tip [W3C](https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2) reglamenta que > <i>Cuando sólo hay un campo de entrada de texto de una sola línea en un formulario, el agente usuario debe aceptar <b>Enter</b> en ese campo como una solicitud para enviar el formulario.</i> Para prevenir este comportamiento, puede agregar `@submit.native.prevent` on `<el-form>`. ::: ### Formulario inline Cuando el espacio vertical es limitado y la forma es relativamente simple, puede ponerlo en una unica línea. :::demo Establezca el atributo `inline` como `true` y el formulario sera inline. ```html <el-form :inline="true" :model="formInline" class="demo-form-inline"> <el-form-item label="Approved by"> <el-input v-model="formInline.user" placeholder="Approved by"></el-input> </el-form-item> <el-form-item label="Activity zone"> <el-select v-model="formInline.region" placeholder="Activity zone"> <el-option label="Zone one" value="shanghai"></el-option> <el-option label="Zone two" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">Query</el-button> </el-form-item> </el-form> <script> export default { data() { return { formInline: { user: '', region: '' } } }, methods: { onSubmit() { console.log('submit!'); } } } </script> ``` ::: ### Alineamiento Dependiendo de su diseño, hay varias maneras diferentes de alinear el elemento de la etiqueta. :::demo El atributo `label-position` decide cómo se alinean las etiquetas, puede estar `top` o `left`. Cuando se establece en `top`, las etiquetas se colocarán en la parte superior del campo de formulario. ```html <el-radio-group v-model="labelPosition" size="small"> <el-radio-button label="left">Left</el-radio-button> <el-radio-button label="right">Right</el-radio-button> <el-radio-button label="top">Top</el-radio-button> </el-radio-group> <div style="margin: 20px;"></div> <el-form :label-position="labelPosition" label-width="100px" :model="formLabelAlign"> <el-form-item label="Name"> <el-input v-model="formLabelAlign.name"></el-input> </el-form-item> <el-form-item label="Activity zone"> <el-input v-model="formLabelAlign.region"></el-input> </el-form-item> <el-form-item label="Activity form"> <el-input v-model="formLabelAlign.type"></el-input> </el-form-item> </el-form> <script> export default { data() { return { labelPosition: 'right', formLabelAlign: { name: '', region: '', type: '' } }; } } </script> ``` ::: ### Validación El componente `form` le permite verificar sus datos, ayudándole a encontrar y corregir errores. :::demo Sólo tiene que añadir el atributo `rules` en el componente `Form`, pasar las reglas de validación y establecer el atributo `prop` para `Form-Item` como una clave específica que necesita ser validada. Ver más información en [async-validator](https://github.com/yiminghe/async-validator). ```html <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px" class="demo-ruleForm"> <el-form-item label="Activity name" prop="name"> <el-input v-model="ruleForm.name"></el-input> </el-form-item> <el-form-item label="Activity zone" prop="region"> <el-select v-model="ruleForm.region" placeholder="Activity zone"> <el-option label="Zone one" value="shanghai"></el-option> <el-option label="Zone two" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="Activity time" required> <el-col :span="11"> <el-form-item prop="date1"> <el-date-picker type="date" placeholder="Pick a date" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-form-item prop="date2"> <el-time-picker type="fixed-time" placeholder="Pick a time" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker> </el-form-item> </el-col> </el-form-item> <el-form-item label="Instant delivery" prop="delivery"> <el-switch v-model="ruleForm.delivery"></el-switch> </el-form-item> <el-form-item label="Activity type" prop="type"> <el-checkbox-group v-model="ruleForm.type"> <el-checkbox label="Online activities" name="type"></el-checkbox> <el-checkbox label="Promotion activities" name="type"></el-checkbox> <el-checkbox label="Offline activities" name="type"></el-checkbox> <el-checkbox label="Simple brand exposure" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="Resources" prop="resource"> <el-radio-group v-model="ruleForm.resource"> <el-radio label="Sponsorship"></el-radio> <el-radio label="Venue"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="Activity form" prop="desc"> <el-input type="textarea" v-model="ruleForm.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">Create</el-button> <el-button @click="resetForm('ruleForm')">Reset</el-button> </el-form-item> </el-form> <script> export default { data() { return { ruleForm: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, rules: { name: [ { required: true, message: 'Please input Activity name', trigger: 'blur' }, { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' } ], region: [ { required: true, message: 'Please select Activity zone', trigger: 'change' } ], date1: [ { type: 'date', required: true, message: 'Please pick a date', trigger: 'change' } ], date2: [ { type: 'date', required: true, message: 'Please pick a time', trigger: 'change' } ], type: [ { type: 'array', required: true, message: 'Please select at least one activity type', trigger: 'change' } ], resource: [ { required: true, message: 'Please select activity resource', trigger: 'change' } ], desc: [ { required: true, message: 'Please input activity form', trigger: 'blur' } ] } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script> ``` ::: ### Reglas personalizadas de validación Este ejemplo muestra cómo personalizar sus propias reglas de validación para finalizar una verificación de contraseña de dos pasos. :::demo Aquí utilizamos el `status-icon` para reflejar el resultado de la validación como un icono. ```html <el-form :model="ruleForm2" status-icon :rules="rules2" ref="ruleForm2" label-width="120px" class="demo-ruleForm"> <el-form-item label="Password" prop="pass"> <el-input type="password" v-model="ruleForm2.pass" auto-complete="off"></el-input> </el-form-item> <el-form-item label="Confirm" prop="checkPass"> <el-input type="password" v-model="ruleForm2.checkPass" auto-complete="off"></el-input> </el-form-item> <el-form-item label="Age" prop="age"> <el-input v-model.number="ruleForm2.age"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm2')">Submit</el-button> <el-button @click="resetForm('ruleForm2')">Reset</el-button> </el-form-item> </el-form> <script> export default { data() { var checkAge = (rule, value, callback) => { if (!value) { return callback(new Error('Please input the age')); } setTimeout(() => { if (!Number.isInteger(value)) { callback(new Error('Please input digits')); } else { if (value < 18) { callback(new Error('Age must be greater than 18')); } else { callback(); } } }, 1000); }; var validatePass = (rule, value, callback) => { if (value === '') { callback(new Error('Please input the password')); } else { if (this.ruleForm2.checkPass !== '') { this.$refs.ruleForm2.validateField('checkPass'); } callback(); } }; var validatePass2 = (rule, value, callback) => { if (value === '') { callback(new Error('Please input the password again')); } else if (value !== this.ruleForm2.pass) { callback(new Error('Two inputs don\'t match!')); } else { callback(); } }; return { ruleForm2: { pass: '', checkPass: '', age: '' }, rules2: { pass: [ { validator: validatePass, trigger: 'blur' } ], checkPass: [ { validator: validatePass2, trigger: 'blur' } ], age: [ { validator: checkAge, trigger: 'blur' } ] } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script> ``` ::: ### Eliminar o agregar validaciones dinamicamente :::demo Además de pasar todas las reglas de validación al mismo tiempo en el componente `form`, también puede pasar las reglas de validación o borrar reglas en un único campo de formulario de forma dinámica. ```html <el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="120px" class="demo-dynamic"> <el-form-item prop="email" label="Email" :rules="[ { required: true, message: 'Please input email address', trigger: 'blur' }, { type: 'email', message: 'Please input correct email address', trigger: 'blur,change' } ]" > <el-input v-model="dynamicValidateForm.email"></el-input> </el-form-item> <el-form-item v-for="(domain, index) in dynamicValidateForm.domains" :label="'Domain' + index" :key="domain.key" :prop="'domains.' + index + '.value'" :rules="{ required: true, message: 'domain can not be null', trigger: 'blur' }" > <el-input v-model="domain.value"></el-input><el-button @click.prevent="removeDomain(domain)">Delete</el-button> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('dynamicValidateForm')">Submit</el-button> <el-button @click="addDomain">New domain</el-button> <el-button @click="resetForm('dynamicValidateForm')">Reset</el-button> </el-form-item> </el-form> <script> export default { data() { return { dynamicValidateForm: { domains: [{ key: 1, value: '' }], email: '' } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); }, removeDomain(item) { var index = this.dynamicValidateForm.domains.indexOf(item); if (index !== -1) { this.dynamicValidateForm.domains.splice(index, 1); } }, addDomain() { this.dynamicValidateForm.domains.push({ key: Date.now(), value: '' }); } } } </script> ``` ::: ### Validación numerica :::demo La validacion numerica necesita un modificador `.number` añadido en el enlace `v-model` de entrada, sirve para transformar el valor de la cadena al número proporcionado por Vuejs. ```html <el-form :model="numberValidateForm" ref="numberValidateForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="age" prop="age" :rules="[ { required: true, message: 'age is required'}, { type: 'number', message: 'age must be a number'} ]" > <el-input type="age" v-model.number="numberValidateForm.age" auto-complete="off"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('numberValidateForm')">Submit</el-button> <el-button @click="resetForm('numberValidateForm')">Reset</el-button> </el-form-item> </el-form> <script> export default { data() { return { numberValidateForm: { age: '' } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script> ``` ::: :::tip Cuando un `el-form-item` está anidado en otro `el-form-item`, su ancho de etiqueta será 0. Si es necesario, puede establecer el ancho de etiqueta en ese `el-form-item`. ::: ### Tamaño del control Todos los componentes de un formulario heredan su atributo `size`. De manera similar, FormItem también tiene un atributo `size`. :::demo Aún así, puede ajustar el `size` de cada componente si no desea que herede su tamaño de From o FormItem. ```html <el-form ref="form" :model="sizeForm" label-width="120px" size="mini"> <el-form-item label="Activity name"> <el-input v-model="sizeForm.name"></el-input> </el-form-item> <el-form-item label="Activity zone"> <el-select v-model="sizeForm.region" placeholder="please select your zone"> <el-option label="Zone one" value="shanghai"></el-option> <el-option label="Zone two" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="Activity time"> <el-col :span="11"> <el-date-picker type="date" placeholder="Pick a date" v-model="sizeForm.date1" style="width: 100%;"></el-date-picker> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-time-picker type="fixed-time" placeholder="Pick a time" v-model="sizeForm.date2" style="width: 100%;"></el-time-picker> </el-col> </el-form-item> <el-form-item label="Activity type"> <el-checkbox-group v-model="sizeForm.type"> <el-checkbox-button label="Online activities" name="type"></el-checkbox-button> <el-checkbox-button label="Promotion activities" name="type"></el-checkbox-button> </el-checkbox-group> </el-form-item> <el-form-item label="Resources"> <el-radio-group v-model="sizeForm.resource" size="medium"> <el-radio border label="Sponsor"></el-radio> <el-radio border label="Venue"></el-radio> </el-radio-group> </el-form-item> <el-form-item size="large"> <el-button type="primary" @click="onSubmit">Create</el-button> <el-button>Cancel</el-button> </el-form-item> </el-form> <script> export default { data() { return { sizeForm: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' } }; }, methods: { onSubmit() { console.log('submit!'); } } }; </script> ``` ::: ### Form Atributos | Atributo | Descripción | Tipo | Valores aceptados | Por defecto | | -------------- | ---------------------------------------- | ------- | --------------------- | ----------- | | model | Datos del componente | object | — | — | | rules | Reglas de validación | object | — | — | | inline | Si el form es inline | boolean | — | false | | label-position | Posicion de la etiqueta | string | left / right / top | right | | label-width | ancho de la etiqueta, y todos los form items directos descendientes heredarán este valor | string | — | — | | label-suffix | sufijo de la etiqueta | string | — | — | | show-message | si mostrar o no el mensaje de error | boolean | — | true | | inline-message | si desea visualizar el mensaje de error inline con la posición del form item | boolean | — | false | | status-icon | si desea visualizar un icono que indique el resultado de la validación | boolean | — | false | | validate-on-rule-change | whether to trigger validation when the `rules` prop is changed | boolean | — | true | | size | el tamaño de los componentes en este form | string | medium / small / mini | — | | disabled | whether to disabled all components in this form. If set to true, it cannot be overridden by its inner components' `disabled` prop | boolean | — | false | ### Form Metodos | Metodo | Descripción | Parametros | | ------------- | ---------------------------------------- | ---------------------------------------- | | validate | el método para validar todo el formulario. Devuelve una promesa si se omite el return | Function(callback: Function(boolean)) | | validateField | el método para validar un determinado form item | Function(prop: string, callback: Function(errorMessage: string)) | | resetFields | restablece todos los campos y elimina el resultado de validación | — | | clearValidate | limpia mensaje de validación para todos los campos | - ### Form-Item Atributos | Atributo | Descripción | Tipo | Valores aceptados | Por defecto | | -------------- | ---------------------------------------- | ------- | ----------------------------------- | ----------- | | prop | un key de `model`. En el uso del método validate and resetFields, el atributo es obligatorio. | string | keys of model that passed to `form` | | | label | etiqueta | string | — | — | | label-width | ancho de la etiqueta, e.g. '50px' | string | — | — | | required | si el campo es obligatorio o no, estará determinado por las reglas de validación si se omite. | string | — | false | | rules | reglas de validacion del form | object | — | — | | error | mensaje de error de campo, establezca su valor y el campo validará el error y mostrará este mensaje inmediatamente. | string | — | — | | show-message | si mostrar o no el mensaje de error | boolean | — | true | | inline-message | mensaje de validación estilo inline | boolean | — | false | | size | Tamaño de los componentes en este form item | string | medium / small / mini | - | ### Form-Item Slot | Nombre | Descripción | | ------ | ------------------------ | | — | contenido del Form Item | | label | contenido de la etiqueta | ### Form-Item Metodo | Metodo | Descripción | Parametros | | ---------- | ---------------------------------------- | ---------- | | resetField | restablecer campo actual y eliminar resultado de validación | — |