Tutoriel VueJS 3 – Liaison des classes et des styles

 

Dans cette leçon, nous allons examiner le concept de liaison de classe et de style.

Notre objectif

Lier des classes et des styles à nos éléments en fonction des données de notre application.

Liaison du style

Dans la dernière leçon, nous avons ajouté une fonction qui permet de mettre à jour l’image affichée en survolant le mot « bleu » ou « rouge », c’est-à-dire les T-Shirt bleues ou rouges. Mais l’expérience de l’utilisateur ne serait-elle pas plus agréable si, au lieu de survoler le *mot « *bleu » ou « *rouge », nous survolions les couleurs réelles bleues et rouges ?

index.html
 <div class="variants-wrapper">
  <div
    v-for="variant in variants"
    :key="variant.id"
    @mouseover="updateImage(variant.image)"
    class="color-circle"
    >
  </div>
</div>

Cette classe est déjà présente dans notre fichier css. Comme vous pouvez le voir, elle transforme simplement nos divs en un cercle d’un diamètre de 50px :

styles.css
.variants-wrapper {
    display: flex;
    gap: 10px;
}
.color-circle {
  width: 50px;
  height: 50px;
  margin-top: 8px;
  border: 2px solid #d8d8d8;
  border-radius: 50%;
  cursor: pointer;
}

Maintenant que ce point est réglé, nous pouvons passer à la liaison des styles proprement dite. Comme il se doit, nous voulons lier les styles aux divs de la variante. Pour ce faire, nous utilisons v-bind (ou son raccourci 🙂 sur l’attribut de style, et nous y associons un objet de style.

index.html
 <div class="variants-wrapper">
  <div
    v-for="variant in variants"
    :key="variant.id"
    @mouseover="updateImage(variant.image)"
    class="color-circle"
    :style="{ backgroundColor: variant.color }">
  </div>
</div>
main.js
const app = Vue.createApp({
    data() {
        return {
            ...
            variants: [
                { id: 2234, color: '#0000FF', image: './assets/images/t-shirt-bleu.png' },
                { id: 2235, color: '#FF0000', image: './assets/images/t-shirt-rouge.png' }
            ]
        }
    },
})

Ici, nous définissons la couleur d’arrière-plan des divs comme étant égale à la déclinaison de couleur. Ainsi, au lieu d’afficher les mots « bleu » et « rouge », nous utilisons les codes hexadécimal pour définir la couleur de fond de nos cercles.

En vérifiant dans le navigateur, nous devrions maintenant voir deux cercles de couleur remplis d’un fond bleu et rouge.

Cool ! Comprenons maintenant, à un niveau plus profond, comment tout cela fonctionne.

Comprendre la laison de style

Sur notre div variante, nous avons ajouté l’attribut style et lié un objet style à celui-ci.

index.html
<div 
  ...
  :style="{ backgroundColor: variant.color }">
</div>

Cet objet de style possède la propriété CSS backgroundColor, et nous la définissons comme étant égale à la couleur de la variante au moment de l’itération v-for.

Dans la première itération, variant.color est « #0000FF ».

Vue prend cette information et la convertit en code :style="{ backgroundColor : "0000ff" }"

Puis affiche un cercle à fond bleu avec un code couleur rgb.

Il répète ce processus pour la deuxième couleur de variante afin de créer le cercle rouge.

Camel vs Kebab

Il faut tenir compte de certains éléments importants lorsqu’on utilise une reliure de style comme celle-ci.

<div :style="{ backgroundColor: variant.color }>

À l’intérieur de cette expression, rappelez-vous que cet objet de style est entièrement en JavaScript. C’est pourquoi j’ai utilisé la casse camel dans le nom de la propriété. Si j’avais dit background-color, ça aurait été interprété comme le signe négatif moins ( ). Mais nous ne faisons pas de maths ici. Nous définissons un nom de propriété CSS.

Donc, puisque nous sommes dans cet objet JavaScript, nous devons respecter la casse camel, à moins que nous ne voulions utiliser « kebab-case » entre guillemets pour éviter une mauvaise interprétation mathématique, comme ceci :

<div :style="{ 'background-color': variant.color }>

Les deux options fonctionnent mais n’oubliez pas les guillemets dans le second cas, à vous de voir ce que vous préférez.

Liaison de style: Objects

Il arrive parfois que l’on veuille ajouter un certain nombre de styles à un élément, mais les ajouter tous en ligne peut être désordonné. Dans ces situations, nous pouvons nous lier à un objet de style entier qui vit dans nos données.

index.html
<div :style="styles"></div>
main.js
data() {
    return {
        styles: {
            color: '#ff0000',
            fontSize: '14px'
        }
    }
}

Il arrive parfois que l’on veuille ajouter un certain nombre de styles à un élément, mais les ajouter tous en ligne peut être désordonné. Dans ces situations, nous pouvons nous lier à un objet de style entier qui vit dans nos données.

Liaison de classe

De retour dans notre application, vous remarquerez que lorsque la valeur de notre donnée inStock est fausse, nous pouvons toujours cliquer sur le bouton Ajouter au panier et incrémenter la valeur du panier. Mais si le produit n’est pas en stock, nous ne voulons peut-être pas que l’utilisateur puisse ajouter le produit au panier. Changeons donc ce comportement, en désactivant le bouton lorsque inStock est faux ET en faisant apparaître le bouton désactivé, à l’aide de la liaison de classe.

Pour commencer, nous allons utiliser l’abréviation v-bind sur l’attribut disabled pour ajouter cet attribut lorsque notre produit n’est pas en stock.

index.html
<button 
  class="button" 
  :disabled="!inStock" 
  @click="addToCart">
  Ajouter au panier
</button>

Désormais, lorsque inStock est faux et que nous cliquons sur le bouton Ajouter au panier, rien ne se passe puisque celui-ci est désactivé. Mais le bouton apparaît toujours actif, ce qui est trompeur pour nos utilisateurs. Utilisons donc la liaison de classe pour ajouter également une classe disabledButton, lorsque inStock est faux.

Vous verrez dans notre fichier CSS que nous avons déjà cette classe disabledButton, qui définit la couleur d’arrière-plan en gris et interdit l’utilisation du curseur.

styles.css
.disabledButton {
  background-color: #d8d8d8;
  cursor: not-allowed;
}

Pour appliquer cette classe de manière conditionnelle, en fonction de la valeur de inStock, nous utiliserons le raccourci v-bind sur l’attribut class, et utiliserons une expression qui ajoute la classe disabledButton (ou non) lorsque !inStock.

index.html
<button 
  class="button" 
  :class="{ disabledButton: !inStock }" 
  :disabled="!inStock" 
  @click="addToCart">
  Ajouter au panier
</button>

Désormais, si inStock est faux, non seulement le bouton sera désactivé, mais il apparaîtra également désactivé.

Multiples classes sur un élément

Lorsque vous commencez à utiliser la liaison de classe, il y a certaines choses à noter. Par exemple, que se passe-t-il lorsque nous avons déjà une classe existante et que nous voulons ajouter une autre classe de manière conditionnelle en fonction d’une valeur de données ?

Par exemple, si nous avons déjà la classe color-circle sur ce div, et que nous ajoutons conditionnellement la classe active, à quoi cela ressemblera-t-il ?

Ces classes vont être combinées comme suit :

<div class="color-circle active"></div>

Opérateurs ternaires

Un outil utile que la liaison de classe nous donne est la possibilité d’utiliser des opérateurs ternaires en ligne pour ajouter différentes classes en fonction d’une condition.

Dans ce cas, puisque activeClass est vrai, nous ajoutons effectivement la classe active. S’il était faux, nous n’ajouterions pas de classe sinon, nous aurions pu ajouter une classe entièrement différente.

Conclusion

Les variations de syntaxe et les cas d’utilisation que je viens de vous montrer avec la liaison de classe et de style ne sont que le début. Je vous recommande donc de consulter la documentation de Vue pour plus de cas d’utilisation et d’exemples.

Ressources

Pensez à télécharger le code de départ pour commencer cette étape du tutoriel dans de bonnes conditions.

Nouveau Tutoriel

Newsletter

Ne manquez jamais les nouveaux conseils, tutoriels et autres.

Pas de spam, jamais. Nous ne partagerons jamais votre adresse électronique et vous pouvez vous désabonner à tout moment.