6. Proyecto [vuejs-04]: directrices [v-model, v-bind], atributos calculados, formulario de entrada
La estructura del proyecto [vuejs-04] es la siguiente:

6.1. El script principal [main.js]
Es el mismo que en el ejemplo anterior.
6.2. El componente principal [App]
El código de [App.vue] es el siguiente:
<template>
<b-container>
<b-card>
<!-- mensaje de presentación -->
<b-row>
<b-col cols="8">
<b-alert show variant="success" align="center">
<h4>[vuejs-04] : directives [v-model, v-bind], attributs calculés, formulaire de saisie</h4>
</b-alert>
</b-col>
</b-row>
<Form />
</b-card>
</b-container>
</template>
<script>
import Form from "./components/Form.vue";
export default {
name: "app",
components: {
Form
}
};
</script>
El componente [App.vue] utiliza el nuevo componente [Form] (líneas 12, 19, 24).
6.3. El componente [Form]
El código del componente [Form] es el siguiente:
<template>
<div>
<!-- formulario -->
<b-form>
<!-- elementos del formulario -->
<b-row>
<b-col cols="4">
<b-card bg-variant="light">
<b-form-group label="Nombre d'enfants à charge" label-for="enfants">
<b-input type="text"
id="enfants"
placeholder="Indiquez votre nombre d'enfants"
v-model="enfants"
v-bind:state="enfantsValide" />
<b-form-invalid-feedback :state="enfantsValide">Vous devez saisir un nombre positif ou nul</b-form-invalid-feedback>
</b-form-group>
<!-- botón -->
<b-button variant="primary" :disabled="formInvalide" @click="doSomething">Valider</b-button>
</b-card>
</b-col>
</b-row>
</b-form>
<b-row class="mt-3">
<b-col cols="4">
<b-alert show variant="warning" align="center">
<h4>enfants= {{enfants}}</h4>
</b-alert>
</b-col>
</b-row>
</div>
</template>
<!-- script -->
<script>
export default {
// nombre
name: "Form",
// atributos estáticos del componente
data() {
return {
// número de hijos
enfants: ""
};
},
// atributos calculados
computed: {
// atributo [formInvalide]
formInvalide() {
return !this.enfantsValide;
},
// atributo [enfantsInvalide]
enfantsValide() {
return Boolean(this.enfants.match(/^\s*\d+\s*$/));
}
},
// métodos
methods: {
doSomething() {
// se conoce el número de hijos al momento de la validación
alert("Nombre d'enfants : " + this.enfants);
}
}
};
</script>
Representación visual


Comentarios
- líneas 4-32: la etiqueta <b-form> introduce un formulario de Bootstrap;
- línea 6: la etiqueta <b-row> introduce una fila en el formulario;
- línea 7: la etiqueta <b-col cols=’4’> introduce una columna que ocupa 4 columnas de Bootstrap;
- línea 8: la etiqueta <b-card> [6] introduce una tarjeta de Bootstrap, un área enmarcada por un borde;
- línea 9: la etiqueta <b-form-group> introduce un grupo de elementos del formulario vinculados entre sí. Aquí, un texto (atributo [label]) [1] está vinculado a un campo de entrada (atributo [label-for]). El valor de [label-for] es el valor del campo [id], línea 12, del campo de entrada;
- líneas 10-14: la etiqueta <b-input> [2] introduce un campo de entrada:
- línea 10: [type=’text’] indica que se puede escribir texto en el campo de entrada. Se podría haber escrito [type=’number’] con restricciones [min=’val1’ max=’val2’ step=’val3’], ya que se espera un número de elementos hijos. Se ha utilizado [type=’text’] para mostrar cómo verificar la validez de una entrada;
- línea 12: el atributo [placeholder] [3] establece el mensaje que se muestra en el campo de entrada mientras el usuario no haya ingresado nada;
- línea 13: la directiva [v-model] vincula, de manera bidireccional, el valor ingresado con el atributo [enfants], línea 42, del componente:
- cuando cambia el valor ingresado, también cambia el valor del atributo [enfants];
- cuando cambia el valor del atributo [enfants], entonces también cambia el valor ingresado, es decir, cambia el contenido de [2];
- lo importante que hay que entender es que, gracias al mecanismo anterior, cuando el usuario hace clic en el botón [Valider] [5], el atributo [enfants] de la línea 42 toma como valor el valor ingresado en [2];
- línea 14: la directiva [v-bind] establece una relación entre, por un lado, un atributo de la etiqueta <b-input> —en este caso, el atributo [state]— y, por otro, un atributo del componente —en este caso, [enfantsValide]—, en la línea 53. El atributo [enfantsValide] es especial en el sentido de que es una función que devuelve el valor del atributo. A este tipo de atributo se le denomina «atributo calculado». Los atributos calculados se encuentran en la propiedad [computed], línea 47, del componente. Los atributos calculados se utilizan de la misma manera que los atributos estáticos de la función [data]: en la línea 14 no se escribe [v-bind:state=’enfantsValide()’], sino [v-bind:state=’enfantsValide’], sin los paréntesis. Además, al leer el [template], no se puede distinguir un atributo calculado de un atributo estático. Para ello, hay que revisar el código del script del componente;
- línea 14: el atributo [state] determinará el estado válido o inválido del valor ingresado: si [enfantsValide] devuelve el valor [true], el valor ingresado se considera válido; de lo contrario, se considera inválido. La captura de pantalla anterior muestra el componente [b-input] cuando la función [enfantsValide] devuelve el valor [false];
- línea 15: la etiqueta <b-form-invalid-feedback> [4] permite mostrar un mensaje cuando la entrada en [2] no es válida. Su atributo [:state=’enfantsValide’] es idéntico al atributo [v-bind:state=’enfantsValide’] de la línea 14. Se puede omitir la directiva [v-bind], pero hay que conservar el signo [:]. Por lo tanto, el mensaje de error aparece cuando el atributo [enfantsValide] tiene el valor [false];
- línea 16: fin del grupo de elementos <b-group>;
- línea 18: el botón [5] que permitirá validar la entrada:
- será de color azul [variant=’primary’];
- [:disabled="formInvalide"]: el atributo [disabled] permite habilitar o deshabilitar el botón. Este atributo está vinculado (v-bind) al atributo calculado [formInvalide] de la línea 49;
- [@click="doSomething"]: cuando el usuario haga clic en el botón, se ejecutará el método [doSomething], línea 59;
- líneas 19-22: cierre de las distintas etiquetas abiertas;
- líneas 23-29: se agrega una nueva línea en [template]. [class=’mt-3’] significa [margin (m) top (t) égale à 3 spacers]. [spacer] es una medida de espaciado de Bootstrap. Esta clase genera el espaciado [8] en la captura de pantalla anterior. Sin esta clase, el área [7] queda pegada al área [1-6];
- línea 24: una columna que ocupa 4 columnas de Bootstrap;
- líneas 25-27: una alerta [warning] que muestra el valor del atributo estático [enfants] (línea 42). Dado que este atributo tiene un enlace bidireccional con el campo de entrada, tan pronto como el usuario modifica este último, el valor que se muestra en la alerta también cambia;
- líneas 34-65: el código jS del componente;
- línea 42: el único atributo estático del componente;
- líneas 47-56: los atributos calculados del componente;
- líneas 53-55: la entrada se considera válida si es un número entero positivo, que puede ir precedido o seguido de «espacios»;
- líneas 49-51: el formulario se considera válido si la entrada del número de hijos es válida. Por lo general, un formulario tiene varias entradas y se considera válido si todas ellas son válidas;
- líneas 58-63: los métodos del componente que responden a sus eventos. Aquí solo hay un evento: el [click] en el botón. Simplemente se muestra el valor ingresado para demostrar que se tiene acceso a él;
6.4. Ejecución del proyecto
Modificamos el archivo [package.json] y ejecutamos el proyecto:
