Apparence
Théorie - Semaine 11 - Liaisons et événements
Liaison de propriétés
Rappel
Jusqu'a maintenant, nous avons vu l'interpolation de string avec la syntaxe de moustache (doubles accolades). Combiné avec ref, cela nous a permis de faire du rendu dynamique dans notre application. Cependant, il existe d'autres types de liaisons que nous pouvons faire dans Vue.js, notamment la liaison de propriétés.
La syntaxe de liaison de propriétés
La syntaxe de liaison de propriétés en Vue.js utilise les deux points : ou la directive v-bind. Cela permet de lier une propriété d'un élément HTML à une expression JavaScript. Par exemple, ajoutons un bouton de test avec la propriété disabled qui est liée à une variable estDesactivee :
vue
<script setup lang="ts">
import ArticlesService from '@/services/articles.ts';
import {Ordre} from '@/typings/ordre.ts';
import { useRouter } from 'vue-router';
const props = defineProps({ nom: { type: String, required: true } });
const service = new ArticlesService();
const article = service?.chercher(props.nom);
const router = useRouter();
const estDesactivee = true;
/**
* Retourner à la page des articles
*/
function retourPageArticles(){
router.push({ name: 'articles', query: { ordre: Ordre.asc } });
}
</script>
<template>
<h2>Détails d'un article</h2>
<div v-if="article">
<div>{{ article.nom }}</div>
<div>{{ article.prix }}</div>
</div>
<div v-else>
Impossible de trouver l'article
</div>
<button
class="btn btn-primary"
@click="retourPageArticles"
>
Retour
</button>
<button :disabled="estDesactivee">
Test
</button>
</template>Ici, puisque estDesactivee est égal à true, le bouton "Test" sera désactivé. Si nous changeons la valeur de estDesactivee à false, le bouton sera activé. Tout ça grâce à la liaison entre la propriété disabled du bouton et la variable estDesactivee.
Truc 💡
Il est préférable d'utiliser la liaison de propriété pour les attributs et l'interpolation de String pour le contenu d'une balise.
Liaison de classe CSS
À titre de référence, voici la documentation de Vue sur la liaison de classe CSS.
Il est possible d'ajouter des classes CSS de manière dynamique à un élément HTML en utilisant la syntaxe de liaison de propriétés.
vue
<script setup lang="ts">
//Reste du code
const estDesactivee = true;
const estActivee = true;
const erreur = false;
</script>
<template>
<!-- Reste du code -->
<button
class="btn btn-secondary"
:class="{ active: estActivee, 'text-danger': erreur, full: articles.length > 5 }"
>
Test 2
</button>
</template>La classe active sera ajoutée dans la liste de classes sur le bouton, puisque estActivee est égale à true. Si estActivee est égal à false, la classe active ne sera pas dans la liste de classes CSS. Justement, c'est le cas pour text-danger qui est faux.
Truc 💡
On remarque qu'on peut mettre plusieurs classes potentielles séparées par une virgule. C'est parce que v-bind:class accepte un objet avec comme propriété une liste de classes potentielles.
Attention ⚠
Si la classe a ajouter n'est pas en camelCase, il faut la mettre entre guillemets. Par exemple, pour ajouter la classe text-danger, on doit faire 'text-danger': erreur.
Liaison de style CSS
Il est également possible de lier des styles CSS de manière dynamique à un élément HTML en utilisant la syntaxe de liaison de propriétés.
vue
<script setup lang="ts">
//Reste du code
const estDesactivee = true;
const estActivee = true;
const erreur = false;
const couleurActive = 'beige';
</script>
<template>
<!-- Reste du code -->
<button
class="btn btn-secondary"
:class="{ active: estActivee, 'text-danger': erreur, full: articles.length > 5 }"
:style="{ color: couleurActive, fontSize: 18 + articles.length + 'px' }"
>
Test 2
</button>
</template>Attention ⚠
Il est recommandé d'utiliser les classes CSS le plus possible. Cependant, ça peut être utile si on veut modifier seulement un élément de style dynamiquement comme le font-size.
Liaison d'événement
Comme vu lors de la théorie sur les directives, il est possible d'attacher des événements à un élément HTML en utilisant la directive v-on ou le raccourci @. Il sera possible également de gérer les événements de manière plus complexe en utilisant des méthodes dans la section <script> de votre composant Vue. On ne mettra pas de () car on veut que la méthode soit appelée seulement lors de l'événement.
vue
<script setup lang="ts">
import {useRoute} from 'vue-router';
import {RouterLink} from 'vue-router';
import {ref} from 'vue';
import ArticlesService from '@/services/articles.ts';
import type {Ordre} from '@/typings/ordre.ts';
const titre = ref('Mes articles');
const route = useRoute();
const service = new ArticlesService();
const articles = service.obtenirArticlesAvecOrdre(<Ordre>route.query.ordre);
function sauvegarder() {
alert("La liste d'articles a été sauvegardée avec succès!")
}
</script>
<template>
<h2>{{ titre }}</h2>
<ul>
<li
v-for="article in articles"
:key="article.nom"
>
<router-link
class="nav-link"
:to="{ name: 'article', params: { nom: article.nom } }"
>
{{ article.nom }}
</router-link>
</li>
</ul>
<button
class="btn btn-primary"
@click="sauvegarder"
>
Sauvegarder
</button>
</template>Liaison bidirectionnelle
Il est possible de faire une liaison bidirectionnelle entre une variable dans votre composant Vue et un élément HTML, comme un champ de formulaire. Cela se fait en utilisant la directive v-model.
Par exemple, pour lier une variable nom à un champ de saisie de texte, vous pouvez faire :
vue
<script setup lang="ts">
import {ref} from 'vue';
let nom = ref('');
</script>
<template>
<input v-model="nom" placeholder="Entrez votre nom">
<p>Bonjour, {{ nom }}!</p>
</template>Cela permet à l'utilisateur de saisir son nom dans le champ de texte, et la variable nom sera automatiquement mise à jour avec la valeur saisie. L'inverse est également vrai : si vous modifiez la variable nom dans votre composant Vue, le champ de texte sera mis à jour en conséquence. C'est ce qu'on appelle une liaison bidirectionnelle.
On peut utiliser ces liaisons bidirectionnelles pour tous les champs utilisateurs comme les checkbox, radio, select et autres.
Information ❗
En réalité, en arrière de v-model il y a un raccourci. Par exemple, <input v-model="text"> sera en réalité <input :value="text" @input="event => text = event.target.value">.
C'est Vue qui gère pour nous le raccourci, mais si jamais vous ne voulez pas être bidirectionnelle ou qu'il faut réagir différemment à une mise à jour du texte (par exemple si vous avez un masque sur le champ texte comme pour les téléphones), vous pouvez toujours gérer manuellement avec v-bind:value et @input.