6. projeto [vuejs-04]: diretivas [v-model, v-bind], propriedades computadas, formulário de entrada
A estrutura de diretórios do projeto [vuejs-04] é a seguinte:

6.1. O script principal [main.js]
É o mesmo que no exemplo anterior.
6.2. O componente principal [App]
O código para [App.vue] é o seguinte:
<template>
<b-container>
<b-card>
<!-- message de présentation -->
<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>
O componente [App.vue] utiliza o novo componente [Form] (linhas 12, 19, 24).
6.3. O componente [Form]
O código do componente [Form] é o seguinte:
<template>
<div>
<!-- form -->
<b-form>
<!-- form elements -->
<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>
<!-- button -->
<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 {
// nom
name: "Form",
// attributs statiques du composant
data() {
return {
// nbre d'enfants
enfants: ""
};
},
// attributs calculés
computed: {
// attribut [formInvalide]
formInvalide() {
return !this.enfantsValide;
},
// attribut [enfantsInvalide]
enfantsValide() {
return Boolean(this.enfants.match(/^\s*\d+\s*$/));
}
},
// méthodes
methods: {
doSomething() {
// le nbre d'enfants est connu lorsque la validation a lieu
alert("Nombre d'enfants : " + this.enfants);
}
}
};
</script>
Saída visual


Comentários
- linhas 4–32: a tag <b-form> introduz um formulário Bootstrap;
- linha 6: a tag <b-row> introduz uma linha no formulário;
- linha 7: a tag <b-col cols=’4’> introduz uma coluna que abrange 4 colunas Bootstrap;
- linha 8: a tag <b-card> [6] introduz um cartão Bootstrap, uma área emoldurada por uma borda;
- linha 9: a tag <b-form-group> adiciona um grupo de elementos de formulário ligados entre si. Aqui, um rótulo (o atributo [label]) [1] está ligado a um campo de entrada (o atributo [label-for]). O valor de [label-for] é o valor do campo [id] (linha 12) do campo de entrada;
- linhas 10–14: a tag <b-input> [2] introduz um campo de entrada:
- linha 10: [type='text'] indica que é possível digitar texto no campo de entrada. Poderíamos ter escrito [type='number'] com restrições [min='val1' max='val2' step='val3'], uma vez que esperamos um número de filhos. Utilizámos [type='text'] para demonstrar como validar uma entrada;
- linha 12: o atributo [placeholder] [3] define a mensagem exibida no campo de entrada até que o utilizador introduza algo;
- linha 13: a diretiva [v-model] vincula bidirecionalmente o valor inserido ao atributo [children], linha 42, do componente:
- quando o valor introduzido muda, o valor do atributo [children] também muda;
- quando o valor do atributo [children] muda, o valor inserido também muda, ou seja, o conteúdo de [2] muda;
- O ponto importante a compreender é que, graças ao mecanismo descrito acima, quando o utilizador clica no botão [Validate] [5], o atributo [children] na linha 42 assume o valor introduzido em [2];
- Linha 14: A diretiva [v-bind] estabelece uma ligação entre um atributo da tag <b-input> — neste caso, o atributo [state] — e um atributo do componente — neste caso, [enfantsValide] na linha 53. O atributo [enfantsValide] é único, na medida em que é uma função que devolve o valor do atributo. Este tipo de atributo é designado por atributo computado. Os atributos computados encontram-se na propriedade [computed], linha 47, do componente. Os atributos computados são utilizados da mesma forma que os atributos estáticos da propriedade [data]: Na linha 14, não escrevemos [v-bind:state=’enfantsValide()’], mas sim [v-bind:state=’enfantsValide’], sem os parênteses. Portanto, ao ler o [template], é impossível distinguir um atributo computado de um atributo estático. Para tal, é necessário examinar o código de script do componente;
- Linha 14: O atributo [state] define o estado válido/inválido do valor introduzido: se [enfantsValide] devolver [true], o valor introduzido é considerado válido; caso contrário, é considerado inválido. A captura de ecrã acima mostra o componente [b-input] quando a função [enfantsValide] devolve [false];
- Linha 15: A tag <b-form-invalid-feedback> [4] exibe uma mensagem quando a entrada em [2] é inválida. O seu atributo [:state='childrenValid'] é idêntico ao atributo [v-bind:state='childrenValid'] na linha 14. A diretiva [v-bind] pode ser omitida, mas o símbolo [:] deve ser mantido. A mensagem de erro é, portanto, exibida quando o atributo [childrenValid] é [false];
- linha 16: fim do grupo de elementos <b-group>;
- linha 18: o botão [5] que irá validar a entrada:
- será azul [variant='primary'];
- [:disabled="formInvalide"]: o atributo [disabled] ativa ou desativa o botão. Este atributo está vinculado (v-bind) ao atributo calculado [formInvalide] na linha 49;
- [@click="doSomething"]: quando o utilizador clicar no botão, o método [doSomething] na linha 59 será executado;
- linhas 19–22: fecho das várias tags abertas;
- linhas 23–29: uma nova linha no [template]. [class=’mt-3’] significa [margem (m) superior (t) igual a 3 espaçadores]. [spacer] é uma unidade de espaçamento do Bootstrap. Esta classe cria o espaçamento [8] na captura de ecrã acima. Sem esta classe, a área [7] fica alinhada com as áreas [1-6];
- linha 24: uma coluna que abrange 4 colunas Bootstrap;
- linhas 25–27: um alerta [warning] que exibe o valor do atributo estático [children] (linha 42). Uma vez que este atributo tem uma ligação bidirecional com o campo de entrada, assim que o utilizador o modifica, o valor exibido no alerta também muda;
- linhas 34–65: o código JavaScript do componente;
- linha 42: o único atributo estático do componente;
- linhas 47–56: os atributos calculados do componente;
- linhas 53–55: a entrada é considerada válida se for um número inteiro positivo, opcionalmente precedido ou seguido de espaços;
- linhas 49–51: o formulário é considerado válido se o número de filhos introduzido for válido. Geralmente, um formulário tem vários campos e é considerado válido se todos eles forem válidos;
- linhas 58–63: os métodos do componente que respondem aos seus eventos. Aqui, existe apenas um evento: o [clique] no botão. Limitamo-nos a apresentar o valor introduzido para mostrar que temos acesso ao mesmo;
6.4. Executar o projeto
Modificamos o ficheiro [package.json] e executamos o projeto:
