Introduction à Vue.js

Vue.js est un framework JavaScript progressif, idéal pour construire des interfaces utilisateur interactives et dynamiques. Il est conçu pour être adoptable progressivement, ce qui signifie que vous pouvez commencer avec des fonctionnalités simples et évoluer vers des applications plus complexes.

Avantages de Vue.js :
  • Facile à apprendre et intégrer.
  • Composants réutilisables.
  • Parfait pour les applications SPA (Single Page Application).

Bonnes Pratiques :

  • Décomposez votre projet en composants réutilisables.
  • Nommez vos composants et fichiers de manière descriptive.
  • Évitez d'écrire des méthodes trop longues dans le script.

Installation et Préparation de l’Environnement

Méthode 1 : Utilisation via un CDN

Ajoutez Vue.js directement dans votre projet HTML via une balise <script>. Cette méthode est idéale pour commencer rapidement.

// Ajoutez Vue.js via un CDN
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>

// Exemple minimal
<div id="app">{{ message }}</div>

const app = Vue.createApp({
    data() {
        return {
            message: 'Bonjour Vue.js!'
        };
    }
});
app.mount('#app');
    

Méthode 2 : Installation avec Vue CLI

Vue CLI est un outil en ligne de commande pour générer des projets Vue.js avec une structure optimisée.

  1. Installez Vue CLI : npm install -g @vue/cli
  2. Créez un nouveau projet : vue create mon-projet
  3. Démarrez le serveur de développement : npm run serve

Méthode 3 : Utilisation avec Vite

Vite est une alternative rapide pour configurer un projet Vue.js. Il est particulièrement adapté pour des projets modernes grâce à sa vitesse.

  1. Créez un projet avec Vite : npm create vite@latest mon-projet --template vue
  2. Installez les dépendances : cd mon-projet && npm install
  3. Démarrez le serveur de développement : npm run dev

La Propriété `data` dans Vue.js

La propriété data dans Vue.js est utilisée pour définir des données réactives qui pilotent l’état de l’application. Ces données sont synchronisées automatiquement avec l'interface utilisateur, offrant une expérience fluide et dynamique. Vue.js détecte les changements dans les données et met à jour le DOM sans intervention manuelle.

Qu’est-ce que `data` ?

`data` est une fonction qui retourne un objet contenant des propriétés réactives. Ces propriétés sont accessibles dans votre HTML via des expressions ou des directives. Vue.js utilise un système d’observateurs pour détecter les modifications dans ces données et mettre à jour l’affichage en conséquence.

Déclaration de `data`

Voici comment définir `data` dans une instance Vue :

const app = Vue.createApp({
    data() {
        return {
            message: 'Bonjour Vue.js!',
            compteur: 0
        };
    }
});
app.mount('#app');
    

Dans cet exemple :

  • message et compteur sont des propriétés définies dans `data`.
  • Ces propriétés deviennent automatiquement réactives.
  • Le DOM sera mis à jour si leurs valeurs changent.

Utilisation dans le DOM

Une fois définies, les données de `data` peuvent être utilisées dans le DOM via :

  • Interpolation : Utilisez {{ }} pour afficher les valeurs des données.
  • Directives : Utilisez des directives comme v-bind ou v-model pour lier des données.
// HTML
<div id='app'>
    <p>{{ message }}</p>
    <button @click='compteur++'>
        Incrémenter</button>
    <p>Compteur : {{ compteur }}</p>
</div>
    

Lorsque vous cliquez sur le bouton, la valeur de compteur augmente automatiquement, et le DOM est mis à jour sans effort supplémentaire.

Applications Pratiques

`data` est souvent utilisé dans des cas pratiques comme :

  • Afficher des listes dynamiques (ex. : tableau de produits, liste d’utilisateurs).
  • Gérer des formulaires avec des champs liés aux données.
  • Synchroniser l’état d’une application avec les actions de l’utilisateur.
// Exemple : Liste dynamique
const app = Vue.createApp({
    data() {
        return {
            utilisateurs: [
                { nom: 'Alice', age: 25 },
                { nom: 'Bob', age: 30 }
            ]
        };
    }
});
    

Dans le DOM :

<ul>
    <li v-for='utilisateur in utilisateurs'>
        {{ utilisateur.nom }} - {{ utilisateur.age }} ans</li>
</ul>
    

Cette approche rend vos interfaces dynamiques et flexibles, avec une gestion simple des données.

Bonnes Pratiques

  • Noms descriptifs : Donnez des noms clairs et significatifs à vos propriétés pour améliorer la lisibilité du code.
  • Divisez vos données : Si vous avez beaucoup de données, répartissez-les dans plusieurs composants pour une meilleure maintenabilité.
  • Évitez les objets complexes inutilisés : N'incluez dans `data` que ce qui est nécessaire à l'interface utilisateur.

Résumé

  • data est la source de toutes les données réactives dans Vue.js.
  • Les modifications des données se reflètent automatiquement dans le DOM.
  • Utilisez des bonnes pratiques pour garder vos données organisées et claires.

La Propriété `methods` dans Vue.js

La propriété methods dans Vue.js est utilisée pour définir des fonctions ou des actions que votre application peut exécuter. Ces méthodes sont souvent utilisées pour gérer les événements ou encapsuler des logiques complexes liées à vos données ou à votre interface utilisateur.

Déclaration de `methods`

Les méthodes sont définies comme des fonctions dans un objet. Elles sont accessibles dans le HTML via des directives comme @click, ou depuis d'autres méthodes dans le script.

// Déclaration de méthodes dans Vue.js
const app = Vue.createApp({
    data() {
        return {
            compteur: 0
        };
    },
    methods: {
        incrementer() {
            this.compteur++;
        },
        reset() {
            this.compteur = 0;
        }
    }
});

app.mount('#app');
    

Utilisation dans le DOM

Une fois définies, les méthodes peuvent être appelées directement depuis le DOM à l'aide de directives d'événements comme @click, @submit, etc.

// Exemple HTML
<div id='app'>
    <p>Compteur : {{ compteur }}</p>
    <button @click='incrementer'>
        Ajouter</button>
    <button @click='reset'>
        Réinitialiser</button>
</div>
    

Applications Professionnelles

Les méthodes sont souvent utilisées pour :

  • Gérer les événements utilisateur (clics, soumissions de formulaire, etc.).
  • Encapsuler des logiques complexes pour améliorer la lisibilité.
  • Manipuler les données réactives.
  • Appeler des APIs ou exécuter des requêtes asynchrones.
// Exemple : Appel d'une API dans une méthode
const app = Vue.createApp({
    data() {
        return {
            utilisateurs: [],
            erreur: ''
        };
    },
    methods: {
        async chargerUtilisateurs() {
            try {
                const response = await fetch('https://api.example.com/users');
                this.utilisateurs = await response.json();
            } catch (e) {
                this.erreur = 'Impossible de charger les données.';
            }
        }
    }
});

app.mount('#app');
    

Ici, la méthode chargerUtilisateurs récupère des données depuis une API et les stocke dans une propriété réactive. Les erreurs sont également gérées.

Bonnes Pratiques

  • Gardez vos méthodes simples et concentrées sur une seule tâche.
  • Ne manipulez pas directement le DOM dans vos méthodes. Utilisez les fonctionnalités réactives de Vue.
  • Utilisez des noms clairs et descriptifs pour vos méthodes.
  • Évitez de dupliquer des logiques similaires. Envisagez de les extraire dans des fonctions réutilisables.

Résumé

  • methods est utilisé pour définir les fonctions de votre application Vue.js.
  • Les méthodes sont accessibles dans le DOM via des directives comme @click.
  • Utilisez-les pour gérer les événements, encapsuler des logiques ou manipuler des données réactives.
  • Respectez les bonnes pratiques pour garder votre code propre et maintenable.

La Propriété `computed` dans Vue.js

La propriété computed dans Vue.js est utilisée pour définir des propriétés dérivées basées sur d'autres données. Contrairement aux méthodes, les propriétés calculées sont mises en cache et recalculées uniquement lorsque leurs dépendances changent.

Qu’est-ce qu’une Propriété Calculée ?

Une propriété calculée est une fonction qui retourne une valeur basée sur d'autres propriétés. Elle est réactive, ce qui signifie qu'elle sera automatiquement mise à jour si ses dépendances changent.

Déclaration de `computed`

Voici comment définir et utiliser une propriété calculée dans Vue.js :

// Déclaration d'une propriété calculée
const app = Vue.createApp({
    data() {
        return {
            firstName: 'Jean',
            lastName: 'Dupont'
        };
    },
    computed: {
        fullName() {
            return `${this.firstName} ${this.lastName}`;
        }
    }
});

app.mount('#app');
    

Utilisation dans le DOM

Une fois définies, les propriétés calculées peuvent être utilisées dans le DOM comme n'importe quelle donnée réactive :

// Exemple HTML
<div id='app'>
    <p>Nom Complet : {{ fullName }}</p>
    <input v-model='firstName' placeholder='Prénom'>
    <input v-model='lastName' placeholder='Nom'>
</div>
    

Lorsque l'utilisateur modifie les champs de saisie, la propriété calculée fullName est automatiquement mise à jour et reflétée dans le DOM.

Différence entre `methods` et `computed`

Bien qu'une méthode puisse également retourner une valeur dérivée, les propriétés calculées offrent un avantage clé : elles sont mises en cache. Cela signifie qu'elles ne sont recalculées que si leurs dépendances changent, ce qui améliore les performances.

// Méthode vs. Propriété Calculée
const app = Vue.createApp({
    data() {
        return {
            firstName: 'Jean',
            lastName: 'Dupont'
        };
    },
    methods: {
        getFullName() {
            return `${this.firstName} ${this.lastName}`;
        }
    },
    computed: {
        fullName() {
            return `${this.firstName} ${this.lastName}`;
        }
    }
});

// HTML
<p>{{ getFullName() }} </p> // Méthode
<p>{{ fullName }} </p> // Propriété Calculée
    

Applications Pratiques

Les propriétés calculées sont utiles dans plusieurs cas pratiques, comme :

  • Générer des valeurs dérivées, comme des totaux ou des formats personnalisés.
  • Filtrer ou trier des listes basées sur des critères dynamiques.
  • Formater les données pour une meilleure présentation (ex. : formater des dates ou des prix).
// Exemple : Liste triée
const app = Vue.createApp({
    data() {
        return {
            utilisateurs: [
                { nom: 'Alice', age: 25 },
                { nom: 'Bob', age: 30 }
            ]
        };
    },
    computed: {
        utilisateursTries() {
            return this.utilisateurs.sort((a, b) => a.age - b.age);
        }
    }
});

app.mount('#app');
    

Bonnes Pratiques

  • Utilisez `computed` pour les propriétés dérivées complexes et récurrentes.
  • Évitez d'ajouter des effets secondaires dans les propriétés calculées.
  • Combinez `computed` avec des méthodes pour gérer des actions spécifiques basées sur ces calculs.

Résumé

  • `computed` est utilisé pour des valeurs dérivées basées sur d'autres données réactives.
  • Les propriétés calculées sont mises en cache, ce qui les rend plus performantes que les méthodes dans certains cas.
  • Utilisez-les pour garder votre logique claire et éviter les redondances.

La Propriété `watch` dans Vue.js

La propriété watch dans Vue.js est utilisée pour observer et réagir aux changements des données réactives. Contrairement à computed, qui est utilisé pour les calculs basés sur des données, watch est idéal pour exécuter des actions ou déclencher des effets secondaires lorsque les données changent.

Quand Utiliser `watch` ?

Utilisez `watch` lorsque vous devez exécuter une logique complexe ou déclencher des actions asynchrones en réponse à un changement de données, par exemple :

  • Appeler une API lorsque les données changent.
  • Effectuer des validations ou des ajustements basés sur des changements spécifiques.
  • Gérer des effets secondaires comme la journalisation ou la mise à jour de composants externes.

Déclaration de `watch`

Voici comment configurer un observateur dans Vue.js :

// Exemple : Observer un compteur
const app = Vue.createApp({
    data() {
        return {
            compteur: 0
        };
    },
    watch: {
        compteur(nouvelleValeur, ancienneValeur) {
            // Exécute une action chaque fois que 'compteur' change
            console.log(`Compteur changé de ${ancienneValeur} à ${nouvelleValeur}`);
        }
    }
});

app.mount('#app');
    

Observer Plusieurs Propriétés

Vous pouvez également observer plusieurs propriétés :

// Exemple : Observer plusieurs propriétés
const app = Vue.createApp({
    data() {
        return {
            nom: 'Jean',
            age: 30
        };
    },
    watch: {
        nom(nouveauNom, ancienNom) {
            console.log(`Nom changé de ${ancienNom} à ${nouveauNom}`);
        },
        age(nouvelAge, ancienAge) {
            console.log(`Âge changé de ${ancienAge} à ${nouvelAge}`);
        }
    }
});

app.mount('#app');
    

Utiliser avec des Données Profondes

Pour observer des objets ou des tableaux, vous pouvez activer une observation en profondeur en utilisant l’option deep.

// Exemple : Observer un tableau en profondeur
const app = Vue.createApp({
    data() {
        return {
            utilisateurs: [
                { nom: 'Alice', age: 25 },
                { nom: 'Bob', age: 30 }
            ]
        };
    },
    watch: {
        utilisateurs: {
            handler(nouvelleValeur, ancienneValeur) {
                console.log('Liste des utilisateurs mise à jour', nouvelleValeur);
            },
            deep: true
        }
    }
});

app.mount('#app');
    

Applications Pratiques

Voici des exemples concrets où utiliser `watch` :

  • Appeler une API chaque fois qu'un champ de recherche est modifié.
  • Enregistrer automatiquement des données dans une base de données locale lorsque l'utilisateur modifie un formulaire.
  • Déclencher des animations ou des effets en réponse à des événements utilisateur.
// Exemple : API basée sur une recherche
const app = Vue.createApp({
    data() {
        return {
            recherche: '',
            resultats: []
        };
    },
    watch: {
        recherche: {
            handler: async (nouvelleRecherche) => {
                try {
                    const response = await fetch(`https://api.example.com/search?q=${nouvelleRecherche}`);
                    this.resultats = await response.json();
                } catch (e) {
                    console.error('Erreur lors de la recherche :', e);
                }
            },
            immediate: true // Lance immédiatement pour les données initiales
        }
    }
});

app.mount('#app');
    

Bonnes Pratiques

  • Utilisez `watch` pour des actions spécifiques nécessitant des effets secondaires (ex. : appels API).
  • Activez `deep` uniquement lorsque nécessaire pour éviter des surcoûts en performance.
  • Préférez `computed` pour des transformations simples de données.

Résumé

  • `watch` est idéal pour surveiller et réagir aux changements de données.
  • Il prend en charge des fonctionnalités avancées comme l’observation profonde et l’exécution immédiate.
  • Utilisez-le pour des scénarios spécifiques nécessitant des effets secondaires ou une logique complexe.

Hooks du Cycle de Vie dans Vue.js

Les hooks du cycle de vie (ou Lifecycle Hooks) permettent d'exécuter du code à des moments spécifiques du cycle de vie d'un composant. Ils vous donnent un contrôle total sur la manière dont votre application Vue.js est initialisée, mise à jour ou détruite.

Qu'est-ce qu'un Hook du Cycle de Vie ?

Chaque composant Vue traverse une série d'étapes depuis sa création jusqu'à sa destruction. À chaque étape, Vue expose des hooks spécifiques que vous pouvez utiliser pour exécuter du code.

Principales étapes du cycle de vie :
  • Création (Initialisation des données, des méthodes et des observateurs).
  • Montage (Insertion du DOM généré dans la page).
  • Mise à jour (Réaction aux changements de données).
  • Destruction (Nettoyage avant que le composant ne soit retiré).

Liste des Hooks du Cycle de Vie

Voici les principaux hooks disponibles dans Vue.js :

  • beforeCreate : Appelé immédiatement après la création de l'instance, avant l'initialisation des données et des événements.
  • created : Appelé après l'initialisation des données et des événements.
  • beforeMount : Appelé avant que le DOM virtuel ne soit inséré dans le DOM réel.
  • mounted : Appelé après que le composant a été monté dans le DOM.
  • beforeUpdate : Appelé avant une mise à jour du DOM réactif.
  • updated : Appelé après une mise à jour du DOM réactif.
  • beforeUnmount : Appelé juste avant que le composant ne soit détruit.
  • unmounted : Appelé après que le composant a été détruit.

Exemples d'Utilisation

Les hooks du cycle de vie sont particulièrement utiles pour des tâches comme :

  • Initialiser des données ou effectuer des appels API au moment de la création du composant.
  • Configurer des écouteurs d'événements ou des timers au montage.
  • Effectuer des animations ou des transitions après le rendu du composant.
  • Nettoyer les ressources (comme les écouteurs ou les connexions) avant la destruction du composant.
// Exemple : Utilisation des hooks du cycle de vie
const app = Vue.createApp({
    data() {
        return {
            message: 'Bienvenue!',
            timer: null
        };
    },
    created() {
        console.log('Le composant est créé.');
    },
    mounted() {
        console.log('Le composant est monté dans le DOM.');
        this.timer = setInterval(() => {
            console.log('Mise à jour toutes les secondes.');
        }, 1000);
    },
    beforeUnmount() {
        console.log('Le composant va être détruit.');
        clearInterval(this.timer);
    },
    unmounted() {
        console.log('Le composant a été détruit.');
    }
});

app.mount('#app');
        

Applications Professionnelles

Les hooks du cycle de vie sont essentiels pour :

  • Initialiser des connexions API ou des services en temps réel (WebSocket, Firebase).
  • Mettre en place des animations au montage ou à la destruction.
  • Optimiser les performances en libérant les ressources inutilisées.
// Exemple : Connexion WebSocket avec hooks
const app = Vue.createApp({
    data() {
        return {
            socket: null,
            messages: []
        };
    },
    mounted() {
        this.socket = new WebSocket('wss://example.com/socket');
        this.socket.onmessage = (event) => {
            this.messages.push(JSON.parse(event.data));
        };
    },
    beforeUnmount() {
        this.socket.close();
    }
});

app.mount('#app');
        

Bonnes Pratiques

  • Utilisez created pour initialiser les données et les configurations simples.
  • Réservez mounted pour les manipulations nécessitant le DOM (ex. : animations, écouteurs).
  • Nettoyez toujours les ressources dans beforeUnmount pour éviter les fuites de mémoire.
  • Évitez de surcharger les hooks : décomposez les tâches complexes en méthodes distinctes.

Résumé

  • Les hooks du cycle de vie permettent de contrôler le comportement des composants à chaque étape de leur cycle.
  • Ils sont utiles pour initialiser des données, configurer des ressources, et nettoyer les composants.
  • Respectez les bonnes pratiques pour maintenir un code clair et performant.

Les Expressions

Les expressions dans Vue.js sont des fragments de logique qui permettent d'afficher dynamiquement des données, d'effectuer des opérations simples ou de transformer des valeurs directement dans les templates. Elles utilisent la syntaxe moustache {{ }}.

Introduction aux Expressions

Une expression est un code JavaScript simple, évalué et affiché directement dans le DOM. Vue.js lie ces expressions au modèle réactif, ce qui signifie qu'elles se mettent à jour automatiquement lorsque leurs dépendances changent.

Syntaxe de Base

Les expressions sont encadrées par des doubles accolades {{ }}. Voici un exemple simple :

<div>
    Bonjour, {{ nom }} ! // Affiche le contenu de la propriété 'nom'
    Le résultat de 2 + 3 est {{ 2 + 3 }}.
</div>
        

Dans cet exemple :

  • nom est une propriété définie dans data.
  • Vue.js évalue automatiquement l'expression 2 + 3 et affiche 5.

Ce qui est Autorisé dans une Expression

Les expressions dans Vue.js prennent en charge :

  • Les valeurs de propriétés définies dans data.
  • Les appels de méthodes définies dans methods.
  • Les opérations simples (mathématiques, concaténation, ternaires).
<div>
    Bonjour, {{ nom + ' Dupont' }} ! // Concaténation de chaînes
    Vous avez {{ age > 18 ? 'accès autorisé' : 'accès refusé' }}.
</div>
        

Ce qui n’est Pas Autorisé

Les expressions dans Vue.js sont limitées à des fragments de logique simples. Vous ne pouvez pas utiliser :

  • Des instructions complètes comme if, while, ou for.
  • Des blocs de code multiples.
// Exemple invalide
{{ if (age > 18) { return 'OK'; } }}
        

Si vous avez besoin d’une logique plus complexe, utilisez des méthodes ou des propriétés calculées (via computed).

Applications Pratiques des Expressions

Voici quelques exemples pratiques d'utilisation des expressions dans des projets professionnels :

<ul>
    <li v-for='produit in produits'>
        {{ produit.nom }} : {{ produit.prix }} €
    </li>
</ul>

// Transformation simple pour formater une valeur
{{ total.toFixed(2) }} // Affiche le total avec deux décimales
        

Bonnes Pratiques

  • Gardez les expressions simples et faciles à comprendre.
  • Évitez d'intégrer de la logique complexe directement dans les templates.
  • Utilisez des méthodes ou des propriétés calculées pour toute transformation complexe ou répétée.
  • Assurez-vous que toutes les dépendances utilisées dans une expression sont réactives.

Résumé

  • Les expressions permettent d'afficher dynamiquement des données ou des calculs simples.
  • Elles doivent rester simples ; pour des cas complexes, utilisez des méthodes ou computed.
  • Utilisez-les pour enrichir vos templates tout en gardant un code lisible et maintenable.

L'Interpolation

L'interpolation est une fonctionnalité de Vue.js qui permet d'injecter dynamiquement des données dans le DOM. Elle s'effectue grâce à la syntaxe moustache {{ }}, utilisée dans les templates pour afficher des données ou évaluer des expressions simples.

Syntaxe de Base

Voici un exemple d'interpolation basique :

<div>
    Bonjour, {{ nom }} ! // Affiche la propriété 'nom'
    La date d'aujourd'hui est : {{ new Date().toLocaleDateString() }}.
</div>
        

Dans cet exemple :

  • nom est une propriété réactive définie dans data.
  • new Date().toLocaleDateString() est une expression JavaScript évaluée dynamiquement.

L'Interpolation dans les Attributs

L'interpolation peut également être utilisée dans les attributs HTML pour injecter dynamiquement des valeurs. Dans ce cas, on utilise le préfixe v-bind ou sa syntaxe raccourcie :.

<img :src='imageUrl' alt='Description de l\'image'>
// 'imageUrl' est une propriété définie dans 'data'
        

Exemple avec une classe CSS dynamique :

<div :class='{ actif: estActif, erreur: aErreur }'>
    Contenu dynamique
</div>
// Ajoute les classes 'actif' et 'erreur' dynamiquement en fonction des propriétés réactives
        

Utilisation Avancée

L'interpolation supporte les expressions JavaScript simples :

<div>
    Résultat : {{ 5 * 3 }} // Affiche 15
    État : {{ actif ? 'En ligne' : 'Hors ligne' }} // Condition ternaire
</div>
        

Cependant, les expressions complexes doivent être déléguées aux propriétés computed ou aux methods.

Limites de l'Interpolation

L'interpolation ne permet pas :

  • Les instructions comme if ou for.
  • Les blocs de code ou plusieurs expressions combinées.

Pour des scénarios complexes, il est préférable d'utiliser des propriétés methods ou computed.

Applications Pratiques

L'interpolation est utilisée dans de nombreux cas pratiques, comme :

  • Afficher des données utilisateurs : {{ utilisateur.nom }}.
  • Mettre à jour dynamiquement des classes CSS ou des styles.
  • Gérer des listes ou des données conditionnelles dans les vues.
<ul>
    <li v-for='tâche in tâches'>
        {{ tâche.nom }} - {{ tâche.état }}
    </li>
</ul>
// 'tâches' est un tableau d'objets dans 'data'
        

Bonnes Pratiques

  • Limitez l'utilisation de l'interpolation à des expressions simples.
  • Utilisez computed pour des transformations ou des calculs complexes.
  • Assurez-vous que toutes les données utilisées dans les interpolations sont bien réactives.
  • Adoptez des conventions de nommage claires pour les propriétés utilisées dans les interpolations.

Résumé

  • L'interpolation injecte dynamiquement des valeurs dans le DOM via {{ }}.
  • Elle prend en charge les expressions simples, mais pas les instructions complexes.
  • Pour des scénarios avancés, utilisez des propriétés methods ou computed.

Les Modificateurs

Les modificateurs dans Vue.js sont des suffixes ajoutés à des directives pour indiquer des transformations ou des comportements spécifiques. Ils permettent d’affiner ou d’adapter le fonctionnement d’une directive.

Qu'est-ce qu'un Modificateur ?

Un modificateur est un point suivi d'un identifiant (par exemple, .stop). Il peut être appliqué sur des directives comme v-on, v-model, ou v-bind. Chaque modificateur modifie le comportement par défaut de la directive.

<button v-on:click.stop='incrementer()'>Incrémenter</button>
// Le modificateur '.stop' empêche la propagation de l'événement
        

Modificateurs Courants

Sur les Événements (v-on)

  • .stop : Arrête la propagation d'un événement.
  • .prevent : Appelle event.preventDefault() pour empêcher le comportement par défaut.
  • .capture : Active la capture de l'événement (phase de capture).
  • .self : Exécute le gestionnaire uniquement si l'événement est déclenché sur l'élément lui-même.
  • .once : Écoute l'événement une seule fois.
<form v-on:submit.prevent='envoyerFormulaire()'>
    <input type='text' v-model='nom'>
    <button type='submit'>Envoyer</button>
</form>
// '.prevent' empêche le rechargement de la page lors de l'envoi du formulaire
        

Sur les Liaisons Dynamiques (v-bind)

  • .prop : Traite l'attribut comme une propriété DOM au lieu d'un attribut HTML.
  • .camel : Convertit un nom de liaison en notation camelCase (utile pour les attributs SVG).
<input :value.prop='valeurInput'>
// Utilise '.prop' pour définir une propriété DOM directement
        

Sur les Modèles de Données (v-model)

  • .lazy : Met à jour la donnée uniquement après avoir quitté le champ (blur).
  • .number : Convertit automatiquement la valeur en un nombre.
  • .trim : Supprime les espaces en début et fin de chaîne avant de mettre à jour la donnée.
<input v-model.lazy='nom'>
// '.lazy' met à jour 'nom' uniquement après avoir quitté le champ

<input v-model.number='age'>
// '.number' force la conversion en nombre
        

Applications Pratiques

Les modificateurs permettent d’optimiser et de sécuriser les interactions utilisateur. Voici quelques exemples :

  • Empêcher les formulaires de recharger la page avec .prevent.
  • Limiter l’écoute des événements à un clic spécifique avec .self.
  • Appliquer des transformations automatiques aux entrées utilisateur avec .trim et .number.
<div v-on:click.self='afficherMessage()'>
    // Ne réagit au clic que si l'utilisateur clique exactement sur cet élément
</div>
        

Bonnes Pratiques

  • Utilisez les modificateurs pour simplifier votre code et éviter d’écrire manuellement des méthodes pour des tâches simples.
  • Combinez plusieurs modificateurs pour des comportements avancés, par exemple .prevent et .once.
  • Documentez les modificateurs personnalisés pour une meilleure compréhension par votre équipe.

Résumé

  • Les modificateurs affinent le comportement des directives comme v-on, v-bind, et v-model.
  • Ils simplifient l'écriture de fonctionnalités courantes, comme empêcher la propagation d'un événement ou transformer une valeur.
  • Respectez les bonnes pratiques pour garder votre code maintenable et clair.

Directive v-bind

La directive v-bind permet de lier dynamiquement des attributs ou des propriétés d'un élément HTML à des données réactives de Vue.js.

Syntaxe de Base

La syntaxe générale est la suivante :

<img v-bind:src='imageSource' alt='Description'>
        

Ici, la valeur de l'attribut src de l'élément img sera mise à jour automatiquement si la propriété imageSource change.

Syntaxe Raccourcie

Pour simplifier, Vue.js permet d'utiliser une syntaxe raccourcie avec le caractère :.

<img :src='imageSource' alt='Description'>
        

Liaison d'Attributs Multiples

Vous pouvez lier plusieurs attributs d'un élément en même temps en passant un objet à v-bind.

<button v-bind='{ disabled: isDisabled, class: buttonClass }'>
    Cliquer
</button>
        

Utilisation Avancée

Avec v-bind, vous pouvez lier des propriétés DOM spécifiques, comme les classes ou les styles CSS, de manière réactive.

<div :class='{ actif: isActive, erreur: hasError }'>
    Contenu dynamique
</div>

<div :style='{ color: textColor, fontSize: fontSize + \'px\' }'>
    Texte stylisé
</div>
        

Bonnes Pratiques

  • Utilisez la syntaxe raccourcie : pour une meilleure lisibilité.
  • Organisez vos données dans data pour rendre les liaisons claires et maintenables.
  • Documentez vos propriétés dynamiques, surtout si elles sont utilisées dans plusieurs composants.

Résumé

  • v-bind permet de lier dynamiquement des attributs ou des propriétés HTML.
  • La syntaxe raccourcie : simplifie son utilisation.
  • Pour des cas complexes, passez un objet à v-bind pour gérer plusieurs liaisons.

Directive v-if

La directive v-if permet de conditionner l'affichage d'un élément dans le DOM. L'élément associé à un v-if sera ajouté ou supprimé dynamiquement en fonction de la valeur de l'expression.

Syntaxe de Base

Voici un exemple simple utilisant v-if :

<div v-if='isVisible'>
    Cet élément est visible si isVisible est true.
</div>
        

Dans cet exemple :

  • Si isVisible est évalué à true, l'élément est ajouté au DOM.
  • Sinon, l'élément est complètement supprimé du DOM.

Combinaison avec v-else

La directive v-else peut être utilisée immédiatement après un v-if pour afficher un élément alternatif si la condition de v-if est fausse.

<div v-if='isLoggedIn'>
    Bienvenue, utilisateur !
</div>
<div v-else>
    Veuillez vous connecter.
</div>
        

Utilisation de v-else-if

La directive v-else-if permet de tester plusieurs conditions successives. Elle s'utilise entre v-if et v-else.

<div v-if='type === "admin"'>
    Bienvenue, administrateur !
</div>
<div v-else-if='type === "editor"'>
    Bienvenue, éditeur !
</div>
<div v-else>
    Bienvenue, visiteur !
</div>
        

Bonnes Pratiques

  • Utilisez v-if pour des scénarios où l'affichage conditionnel dépend de valeurs rarement mises à jour.
  • Pour un simple masquage (sans suppression du DOM), préférez v-show.
  • Assurez-vous que les conditions utilisées sont claires et maintenables.
  • Évitez les tests imbriqués excessifs. Utilisez des méthodes ou des propriétés calculées pour simplifier la logique.

Applications Pratiques

La directive v-if est particulièrement utile pour :

  • Afficher des éléments uniquement lorsque certaines conditions sont remplies (par exemple, l'état de connexion d'un utilisateur).
  • Gérer des interfaces dynamiques basées sur le rôle ou le type d'utilisateur.
  • Optimiser les performances en supprimant les éléments inutiles du DOM.
<div v-if='produits.length > 0'>
    <ul>
        <li v-for='produit in produits'>{{ produit.nom }}</li>
    </ul>
</div>
<div v-else>
    Aucun produit disponible.
</div>
        

Résumé

  • La directive v-if permet un affichage conditionnel en ajoutant ou en supprimant dynamiquement des éléments du DOM.
  • v-else et v-else-if offrent une logique conditionnelle supplémentaire pour gérer des cas multiples.
  • Pour les cas où la condition change fréquemment, préférez v-show.

Directive v-else

La directive v-else est utilisée pour définir une condition alternative lorsque la directive v-if associée est évaluée à false. Elle doit être immédiatement placée après un élément avec v-if.

Syntaxe de Base

Voici un exemple d'utilisation de v-else :

<div v-if='isConnected'>
    Bienvenue, utilisateur connecté !
</div>
<div v-else>
    Veuillez vous connecter.
</div>
        

Dans cet exemple :

  • Si isConnected est évalué à true, le premier élément est affiché.
  • Sinon, le second élément est affiché.

Utilisation avec des Éléments Simples

Vous pouvez utiliser v-else pour gérer des scénarios simples :

<button v-if='isAdmin'>Accéder au Panneau Admin</button>
<button v-else>Retourner à l'Accueil</button>
        

Règles à Respecter

  • v-else doit être directement après un v-if, sans aucun autre élément ou espace entre les deux.
  • Un seul v-else peut suivre un v-if.

Utilisation Avancée

Dans des scénarios où plusieurs conditions sont nécessaires, utilisez une combinaison de v-if, v-else-if, et v-else.

<div v-if='role === "admin"'>
    Panneau Administrateur
</div>
<div v-else-if='role === "editor"'>
    Panneau Éditeur
</div>
<div v-else>
    Page Utilisateur
</div>
        

Bonnes Pratiques

  • Gardez les conditions simples et lisibles.
  • Préférez des propriétés calculées (computed) pour les tests complexes, afin d'améliorer la lisibilité et la maintenabilité.
  • Assurez-vous que les conditions de v-if et v-else ne se chevauchent pas.

Résumé

  • v-else gère une condition alternative lorsqu'un v-if est évalué à false.
  • Il doit être directement adjacent à un v-if.
  • Pour plusieurs conditions, combinez avec v-else-if.

Directive v-for

La directive v-for permet de parcourir une liste ou un objet et de générer dynamiquement un élément pour chaque item. C'est une fonctionnalité essentielle pour travailler avec des données dynamiques dans Vue.js.

Syntaxe de Base

Pour parcourir un tableau, utilisez la syntaxe suivante :

<ul>
    <li v-for='item in items' :key='item.id'>
        {{ item.name }}
    </li>
</ul>
        

Dans cet exemple :

  • items est un tableau d'objets avec des propriétés id et name.
  • L'attribut :key est essentiel pour optimiser le rendu de Vue et éviter des erreurs potentielles.

Parcourir des Objets

Vous pouvez également parcourir les propriétés d'un objet en utilisant v-for.

<div v-for='(value, key) in object' :key='key'>
    {{ key }}: {{ value }}
</div>
        

Avec des Indices

Si vous avez besoin de l'indice des éléments dans un tableau, vous pouvez l'obtenir en utilisant v-for.

<ul>
    <li v-for='(item, index) in items' :key='index'>
        {{ index + 1 }}. {{ item }}
    </li>
</ul>
        

Gestion des Données Vides

Pour gérer des listes potentiellement vides, combinez v-for avec v-if ou v-else.

<ul>
    <li v-for='item in items' :key='item.id'>
        {{ item }}
    </li>
    <li v-if='items.length === 0'>
        Aucun élément à afficher.
    </li>
</ul>
        

Bonnes Pratiques

  • Utilisez toujours un attribut :key unique pour chaque élément généré par v-for. Cela améliore les performances et évite les erreurs.
  • Si la clé est basée sur un index, assurez-vous que l'ordre des éléments ne change pas dynamiquement.
  • Évitez de trop imbriquer des v-for pour garder votre code lisible.
  • Combinez v-for avec des propriétés calculées (computed) pour filtrer ou transformer les données avant de les afficher.

Applications Pratiques

  • Génération de listes dynamiques, comme des menus, des tableaux, ou des galeries d'images.
  • Affichage d'éléments conditionnels avec v-if et v-for.
  • Parcours des objets pour afficher leurs propriétés dynamiquement.
<table>
    <thead>
        <tr>
            <th>Nom</th>
            <th>Email</th>
        </tr>
    </thead>
    <tbody>
        <tr v-for='user in users' :key='user.id'>
            <td>{{ user.name }}</td>
            <td>{{ user.email }}</td>
        </tr>
    </tbody>
</table>
        

Résumé

  • v-for est utilisé pour parcourir des listes ou des objets et générer dynamiquement des éléments.
  • L'utilisation d'un :key unique est essentielle pour optimiser le rendu.
  • Combinez v-for avec v-if ou des propriétés calculées pour des comportements avancés.

Directive v-model

La directive v-model permet de lier des données de manière bidirectionnelle entre une propriété d’un composant Vue.js et un élément du DOM. Elle est principalement utilisée pour créer des formulaires réactifs.

Syntaxe de Base

Voici un exemple de base :

<input v-model='nom' placeholder='Entrez votre nom'>
<p>Bonjour, {{ nom }} !</p>
        

Dans cet exemple :

  • La valeur de l'élément input est liée à la propriété nom.
  • Lorsque l'utilisateur saisit du texte dans l'input, la propriété nom est automatiquement mise à jour.
  • Le texte affiché dans le paragraphe est mis à jour dynamiquement en fonction de la propriété nom.

Utilisation avec Différents Éléments

La directive v-model peut être utilisée avec divers types d'éléments de formulaire.

Champs Texte

<input type='text' v-model='nom'>
        

Cases à Cocher

<input type='checkbox' v-model='accepteConditions'>
<p>Conditions acceptées : {{ accepteConditions }}</p>
        

Boutons Radio

<input type='radio' value='Homme' v-model='genre'> Homme
<input type='radio' value='Femme' v-model='genre'> Femme
<p>Genre sélectionné : {{ genre }}</p>
        

Listes Déroulantes

<select v-model='pays'>
    <option value='france'>France</option>
    <option value='espagne'>Espagne</option>
</select>
<p>Pays sélectionné : {{ pays }}</p>
        

Liaison Bidirectionnelle

La directive v-model établit une liaison bidirectionnelle. Cela signifie que :

  • Les modifications apportées à la propriété de données mettent à jour l'élément DOM.
  • Les modifications apportées par l'utilisateur sur l'élément DOM mettent à jour la propriété de données.

Bonnes Pratiques

  • Assurez-vous que les propriétés liées à v-model sont initialisées dans les données pour éviter les comportements inattendus.
  • Utilisez des computed ou des methods pour transformer les données au besoin avant ou après leur liaison.
  • Pour les formulaires complexes, regroupez les champs dans un objet dédié dans vos données pour améliorer l'organisation.

Résumé

  • v-model permet une liaison bidirectionnelle entre une propriété et un élément DOM.
  • Il peut être utilisé avec différents types d'éléments de formulaire comme les input, checkbox, radio, et select.
  • La bonne organisation des données et des propriétés est essentielle pour un comportement prévisible.

Directive v-on

La directive v-on est utilisée pour écouter des événements du DOM et exécuter des actions lorsqu'ils sont déclenchés. Elle permet de lier des événements comme click, keyup, ou encore submit à des méthodes ou des expressions dans Vue.js.

Syntaxe de Base

La directive v-on peut être utilisée avec les événements du DOM. Voici un exemple :

<button v-on:click='saluer'>Cliquez-moi</button>
        

Dans cet exemple :

  • L'événement click est lié à la méthode saluer définie dans l'objet Vue.
  • Lorsque l'utilisateur clique sur le bouton, la méthode saluer est exécutée.

Syntaxe Abrégée

Vous pouvez utiliser @ comme raccourci pour v-on. Par exemple :

<button @click='saluer'>Cliquez-moi</button>
        

Écoute des Événements avec des Paramètres

Vous pouvez passer des arguments à la méthode appelée :

<button @click='direBonjour("John")'>Saluer John</button>
        

Écoute des Événements Clavier

La directive v-on peut écouter des événements clavier spécifiques, comme keyup ou keydown. Vous pouvez également utiliser des modificateurs pour cibler des touches spécifiques.

<input @keyup.enter='envoyerMessage' placeholder='Appuyez sur Entrée'>
        

Ici, la méthode envoyerMessage est déclenchée uniquement lorsque l'utilisateur appuie sur la touche Entrée.

Modificateurs

Vue.js propose des modificateurs pour simplifier la gestion des événements. En voici quelques exemples :

  • .stop : Arrête la propagation de l'événement.
  • .prevent : Empêche le comportement par défaut.
  • .self : Ne déclenche l'événement que si la cible est l'élément lui-même.
  • .once : L'événement est écouté une seule fois.
<form @submit.prevent='envoyerFormulaire'>
    <button>Envoyer</button>
</form>
        

Bonnes Pratiques

  • Utilisez des noms de méthodes explicites pour améliorer la lisibilité de votre code.
  • Privilégiez les modificateurs comme .stop et .prevent pour simplifier le contrôle des événements.
  • Regroupez les gestionnaires d'événements dans l'objet methods pour une meilleure organisation.

Applications Pratiques

  • Gestion des interactions utilisateur, comme les clics sur les boutons ou la soumission de formulaires.
  • Écoute des raccourcis clavier pour améliorer l'ergonomie de votre application.
  • Implémentation de fonctionnalités interactives, comme le glisser-déposer ou les menus dynamiques.

Résumé

  • v-on permet d'écouter les événements DOM et d'exécuter des actions associées.
  • La syntaxe abrégée @ simplifie l'écriture des gestionnaires d'événements.
  • Les modificateurs comme .prevent, .stop, ou .once offrent un meilleur contrôle sur les comportements des événements.

Directive v-bind

La directive v-bind est utilisée pour lier dynamiquement des attributs à des expressions JavaScript. Elle est essentielle pour passer des données dynamiques dans des attributs HTML tels que src, href, class, ou encore style.

Syntaxe de Base

Voici un exemple simple de v-bind :

<img v-bind:src='imageUrl' alt='Description de l'image'>
        

Dans cet exemple :

  • imageUrl est une propriété définie dans l'objet Vue.
  • L'attribut src de l'image est mis à jour dynamiquement en fonction de la valeur de imageUrl.

Syntaxe Abrégée

Vous pouvez utiliser : comme raccourci pour v-bind. Par exemple :

<a :href='lienUrl'>Visitez ce site</a>
        

Utilisation avec des Attributs Dynamiques

Lier un Attribut `src`

<img :src='imageUrl' alt='Image Dynamique'>
        

Lier un Attribut `href`

<a :href='lienUrl' target='_blank'>Cliquez ici</a>
        

Lier des Classes Dynamiques

Vous pouvez utiliser v-bind:class pour appliquer des classes dynamiques :

<div :class='{ actif: isActive, desactive: !isActive }'>
    Statut
</div>
        

Ici, la classe actif est ajoutée si isActive est true, sinon la classe desactive est ajoutée.

Lier des Styles Dynamiques

Utilisez v-bind:style pour appliquer des styles CSS dynamiques.

<div :style='{ color: textColor, fontSize: fontSize + "px" }'>
    Texte stylisé
</div>
        

Sécurisation et Bonnes Pratiques

  • Évitez d'injecter des données non vérifiées dans des attributs liés pour prévenir les vulnérabilités XSS.
  • Utilisez des propriétés calculées (computed) pour simplifier les expressions complexes.
  • Privilégiez les liaisons abrégées (:) pour améliorer la lisibilité.

Applications Pratiques

  • Lier des images dynamiques dans une galerie.
  • Créer des boutons avec des liens dynamiques basés sur les données utilisateur.
  • Appliquer des classes et styles conditionnels pour des interfaces interactives.

Résumé

  • v-bind permet de lier dynamiquement des attributs à des expressions JavaScript.
  • La syntaxe abrégée (:) simplifie l'écriture.
  • Les liaisons dynamiques avec class et style offrent une flexibilité puissante pour personnaliser l'apparence des éléments.

Directive v-show

La directive v-show permet d'afficher ou de masquer un élément DOM en fonction d'une expression booléenne. Contrairement à v-if, elle ne supprime pas l'élément du DOM, mais modifie sa propriété CSS display.

Syntaxe de Base

Voici un exemple simple :

<div v-show='isVisible'>
    Ceci est visible si isVisible est true.
</div>
        

Dans cet exemple :

  • La propriété isVisible contrôle la visibilité de l'élément.
  • Si isVisible est false, l'élément DOM est masqué avec display: none;.

Différence entre `v-show` et `v-if`

Bien que v-show et v-if permettent tous deux de contrôler l'affichage conditionnel, ils fonctionnent différemment :

  • v-show : L'élément est toujours présent dans le DOM, mais masqué visuellement avec display: none;.
  • v-if : L'élément est ajouté ou supprimé du DOM en fonction de la condition.

Utilisez v-show lorsque la condition change fréquemment et v-if lorsque le coût de suppression/ajout dans le DOM est élevé.

Utilisations Courantes

v-show est utile pour des cas où vous devez contrôler rapidement la visibilité d'un élément sans modifier la structure du DOM.

Masquer/Afficher un Message

<div v-show='isConnected'>
    Bienvenue, utilisateur connecté !
</div>
<div v-show='!isConnected'>
    Veuillez vous connecter pour continuer.
</div>
        

Contrôle d'Interface Utilisateur

<button @click='toggleMenu'>Basculer le menu</button>
<nav v-show='isMenuVisible'>
    <ul>
        <li>Accueil</li>
        <li>À propos</li>
        <li>Contact</li>
    </ul>
</nav>
        

Bonnes Pratiques

  • Privilégiez v-show pour les éléments fréquemment affichés ou masqués (comme un menu déroulant).
  • Évitez d'utiliser v-show pour des éléments complexes nécessitant beaucoup de ressources. Dans ce cas, préférez v-if.
  • Combinez v-show avec des animations CSS ou des transitions pour améliorer l'expérience utilisateur.

Applications Pratiques

  • Afficher un message d'erreur ou une validation dans un formulaire.
  • Basculer la visibilité d'un menu ou d'une boîte de dialogue.
  • Masquer des sections d'une page sans les retirer du DOM.

Résumé

  • v-show contrôle la visibilité d'un élément en modifiant la propriété display.
  • Il est plus performant que v-if lorsque l'état de visibilité change fréquemment.
  • Utilisez-le pour les interactions rapides ou les modifications mineures de l'interface utilisateur.

Directive v-slot

La directive v-slot est utilisée pour définir et consommer des slots dans des composants. Les slots sont une fonctionnalité puissante de Vue.js qui permet d'insérer du contenu dynamique dans des composants enfants, en les rendant hautement réutilisables et personnalisables.

Syntaxe de Base

Voici un exemple simple :

// Composant Parent
<mon-composant>
    <p>Contenu inséré via le slot</p>
</mon-composant>

// Composant Fils
<template>
    <div>
        <slot>Contenu par défaut</slot>
    </div>
</template>
        

Dans cet exemple :

  • Le composant enfant <mon-composant> contient un slot.
  • Le contenu passé par le composant parent est inséré à l'emplacement du slot.
  • Si aucun contenu n'est fourni, le texte Contenu par défaut est affiché.

Slots Nommés

Les slots nommés permettent de définir plusieurs emplacements personnalisés pour le contenu. Chaque slot est identifié par un nom unique.

// Composant Parent
<mon-composant>
    <template v-slot:header>
        <h1>En-Tête</h1>
    </template>
    <template v-slot:footer>
        <p>Pied de page</p>
    </template>
</mon-composant>

// Composant Fils
<template>
    <div>
        <slot name='header'>En-Tête par défaut</slot>
        <slot>Contenu principal</slot>
        <slot name='footer'>Pied de page par défaut</slot>
    </div>
</template>
        

Slots Scopés

Les slots scopés permettent de transmettre des données du composant enfant au contenu inséré par le parent. Cela est utile pour partager des variables ou des états spécifiques.

// Composant Parent
<mon-composant>
    <template v-slot:default='slotProps'>
        <p>Nom : {{ slotProps.nom }}</p>
    </template>
</mon-composant>

// Composant Fils
<template>
    <slot :nom='nom'></slot>
</template>

// Script du Composant Fils
export default {
    data() {
        return {
            nom: 'Jean'
        };
    }
};
        

Dans cet exemple :

  • Le composant enfant transmet la propriété nom au parent via le slot.
  • Le parent accède à la donnée via l'objet slotProps.

Bonnes Pratiques

  • Utilisez des noms descriptifs pour vos slots afin de clarifier leur rôle.
  • Privilégiez les slots scopés pour transmettre des données importantes sans complexifier le composant parent.
  • Ajoutez un contenu par défaut aux slots pour gérer les cas où aucun contenu n'est fourni.

Applications Pratiques

  • Créer des composants réutilisables avec des sections personnalisables comme des cartes ou des modales.
  • Gérer des templates complexes tout en conservant un code propre et modulaire.
  • Transmettre des données spécifiques via des slots scopés pour construire des interfaces dynamiques.

Résumé

  • v-slot est utilisé pour insérer du contenu dynamique dans des composants.
  • Les slots nommés permettent de personnaliser plusieurs sections d'un composant.
  • Les slots scopés permettent de transmettre des données du composant enfant vers le parent.

Custom Directives

Bien que Vue.js propose plusieurs directives intégrées comme v-bind, v-model, et v-if, il est parfois nécessaire de créer vos propres directives personnalisées pour répondre à des besoins spécifiques. Les directives personnalisées vous permettent d'ajouter un comportement à des éléments DOM.

Création de Directives Personnalisées

Les directives personnalisées sont définies avec la méthode app.directive. Voici la structure de base :

// Exemple de directive personnalisée
const app = Vue.createApp({});

app.directive('focus', {
    mounted(el) {
        el.focus(); // Met automatiquement le focus sur l'élément
    }
});
        

Dans cet exemple, la directive v-focus est créée pour automatiquement mettre le focus sur un élément DOM lorsqu'il est monté.

Utilisation d'une Directive Personnalisée

Une fois la directive définie, elle peut être utilisée dans le template comme une directive Vue standard.

<input v-focus placeholder='Focus automatique'>
        

Options Disponibles dans les Directives

Les directives personnalisées prennent en charge plusieurs options pour gérer les différentes étapes du cycle de vie d'un élément DOM.

  • created : Appelé lorsque la directive est attachée à l'élément.
  • beforeMount : Appelé avant que l'élément ne soit inséré dans le DOM.
  • mounted : Appelé lorsque l'élément est inséré dans le DOM.
  • beforeUpdate : Appelé avant la mise à jour de l'élément.
  • updated : Appelé après la mise à jour de l'élément.
  • beforeUnmount : Appelé avant que l'élément ne soit supprimé du DOM.
  • unmounted : Appelé lorsque l'élément est supprimé du DOM.

Exemple avec Plusieurs Hooks

app.directive('highlight', {
    beforeMount(el, binding) {
        el.style.backgroundColor = binding.value; // Applique la couleur initiale
    },
    updated(el, binding) {
        el.style.backgroundColor = binding.value; // Met à jour la couleur si la valeur change
    }
});
        

Paramètres dans les Directives

Les directives personnalisées peuvent recevoir des paramètres via leur objet binding.

  • binding.value : La valeur passée à la directive.
  • binding.arg : Un argument spécifique, comme :arg.
  • binding.modifiers : Les modificateurs appliqués à la directive.

Exemple avec Paramètres

app.directive('color', {
    mounted(el, binding) {
        const color = binding.arg || 'black'; // Définit une couleur par défaut
        el.style.color = color;
        // Vérifie les modificateurs
        if (binding.modifiers.bold) {
            el.style.fontWeight = 'bold';
        }
    }
});
        

Dans ce cas, la directive peut être utilisée comme suit :

<p v-color:blue.bold>Texte en bleu et en gras</p>
        

Bonnes Pratiques

  • Limitez les directives personnalisées à des cas spécifiques pour éviter les redondances avec les fonctionnalités existantes de Vue.
  • Nommez vos directives de manière descriptive pour faciliter leur compréhension.
  • Documentez bien vos directives pour les rendre réutilisables dans d'autres projets.

Applications Pratiques

  • Créer des directives pour la validation de formulaires personnalisées.
  • Gérer les événements globaux ou spécifiques à un élément.
  • Ajouter des animations ou des styles dynamiques aux éléments DOM.

Résumé

  • Les directives personnalisées offrent une flexibilité pour manipuler directement le DOM.
  • Elles sont définies avec app.directive et peuvent être configurées avec plusieurs hooks.
  • Utilisez-les pour des fonctionnalités spécifiques non couvertes par les directives intégrées de Vue.

Component Basics

Les composants sont au cœur de Vue.js. Ils permettent de diviser une application en parties réutilisables et indépendantes, chaque composant encapsulant sa propre logique, structure, et style. Cela facilite la création, la maintenance et la mise à jour des applications complexes.

Qu'est-ce qu'un Composant ?

Un composant est une instance Vue réutilisable définie avec ses propres options. Les composants sont déclarés une fois et peuvent être utilisés plusieurs fois dans une application.

Création d'un Composant

Voici un exemple simple de définition et d'utilisation d'un composant :

// Définir un composant
app.component('mon-composant', {
    template: '<div>Ceci est un composant réutilisable</div>'
});

// Utiliser le composant dans le template
<mon-composant></mon-composant>
        

Dans cet exemple :

  • mon-composant est enregistré comme un composant global.
  • Il peut être utilisé n'importe où dans le template HTML de l'application Vue.

Composants avec Données

Un composant peut inclure ses propres données pour gérer son état interne. Voici comment définir des données dans un composant :

// Définir un composant avec des données
app.component('compteur', {
    data() {
        return {
            compteur: 0
        };
    },
    template: '<div>Compteur : {{ compteur }} <button @click="compteur++">+1</button></div>'
});
        

Ce composant affiche un compteur qui peut être incrémenté en cliquant sur un bouton.

Organisation des Composants

Dans une application complexe, il est conseillé de diviser les composants en fichiers distincts pour une meilleure organisation. Par exemple :

// Fichier compteur.js
export default {
    data() {
        return { compteur: 0 };
    },
    template: '<div>Compteur : {{ compteur }} <button @click="compteur++">+1</button></div>'
};
        

Ensuite, importez et enregistrez ce composant dans l'application principale.

Bonnes Pratiques

  • Découpez votre application en petits composants pour faciliter la maintenance.
  • Utilisez des noms significatifs pour vos composants afin d'améliorer la lisibilité.
  • Évitez de mélanger trop de logique dans un seul composant.

Applications Pratiques

  • Créer des boutons, des modales ou des cartes réutilisables.
  • Organiser les pages d'une application avec des composants parents et enfants.
  • Développer des composants spécifiques pour gérer des fonctionnalités comme les tableaux de données, les graphiques ou les formulaires.

Résumé

  • Les composants sont des blocs de construction modulaires dans Vue.js.
  • Ils peuvent inclure des données, des événements et des styles propres.
  • Ils facilitent la réutilisation et la maintenance de votre application.

Props

Les props (propriétés) permettent à un composant parent de transmettre des données à un composant enfant. Elles sont définies dans le composant enfant et utilisées comme des attributs HTML dans le composant parent.

Qu'est-ce qu'une Prop ?

Une prop est une valeur déclarée par un composant enfant et fournie par un composant parent. Cela permet de créer des composants dynamiques et réutilisables.

Utilisation des Props

Voici un exemple de base :

// Composant enfant
app.component('mon-composant', {
    props: ['message'],
    template: '<p>{{ message }}</p>'
});

// Composant parent
<mon-composant message="Bonjour, Vue.js!"></mon-composant>
        

Dans cet exemple :

  • Le composant enfant utilise la prop message pour afficher du texte.
  • Le composant parent passe la valeur de message en tant qu'attribut.

Validation des Props

Vous pouvez valider les props pour garantir qu'elles respectent les types ou les formats attendus. Cela est particulièrement utile pour les projets complexes.

// Déclaration avec validation
app.component('mon-composant', {
    props: {
        message: {
            type: String,
            required: true,
            default: 'Texte par défaut'
        },
        compteur: {
            type: Number,
            validator(value) {
                return value >= 0; // Doit être positif
            }
        }
    },
    template: '<p>{{ message }} - {{ compteur }}</p>'
});
        

Utilisation Dynamique

Vous pouvez passer des expressions dynamiques comme props à un composant :

<mon-composant :message='dynamicMessage' :compteur='10'></mon-composant>
        

Ici, :message et :compteur sont liés à des données dynamiques du composant parent.

Bonnes Pratiques

  • Validez toujours vos props pour éviter les comportements inattendus.
  • Utilisez des noms descriptifs pour vos props.
  • Ne modifiez jamais directement les props dans le composant enfant. Si vous devez les changer, utilisez une copie locale.

Applications Pratiques

  • Transmettre des données d'un composant parent à un enfant, comme un titre ou un contenu.
  • Créer des composants réutilisables, comme des boutons ou des cartes avec des configurations dynamiques.
  • Faciliter la communication descendante dans les applications Vue.js.

Résumé

  • Les props permettent de transmettre des données des composants parents aux enfants.
  • Elles doivent être déclarées et validées dans le composant enfant.
  • Ne modifiez jamais directement une prop dans un composant enfant : utilisez des données locales si nécessaire.

Custom Events

Les Custom Events (événements personnalisés) permettent aux composants enfants de communiquer avec leurs composants parents. Cela est particulièrement utile pour transmettre des données ou signaler qu'une action a eu lieu.

Pourquoi Utiliser les Custom Events ?

Les props permettent de transmettre des données d'un parent à un enfant. À l'inverse, les événements personnalisés permettent à un enfant d'envoyer des informations à son parent. Cela aide à maintenir une communication unidirectionnelle dans le flux de données.

Émission d'un Événement Personnalisé

Pour émettre un événement, vous utilisez la méthode this.$emit dans le composant enfant. Voici un exemple :

// Composant enfant
app.component('mon-bouton', {
    template: '<button @click="envoyer">Cliquez-moi</button>',
    methods: {
        envoyer() {
            this.$emit('click-event', 'Données envoyées!');
        }
    }
});

// Composant parent
<mon-bouton @click-event='handleEvent'></mon-bouton>

// Méthode du composant parent
methods: {
    handleEvent(data) {
        console.log(data); // Affiche "Données envoyées!"
    }
}
        

Dans cet exemple :

  • Le composant enfant émet un événement nommé click-event.
  • Le parent intercepte cet événement avec @click-event et exécute une méthode.

Transmission de Données via les Événements

Les données peuvent être transmises au parent en tant qu'arguments lors de l'émission de l'événement. Cela permet une communication descendante et ascendante fluide.

Utilisation avec des Composants Réutilisables

Les événements personnalisés sont particulièrement utiles dans les composants réutilisables. Voici un exemple avec un composant formulaire :

// Composant enfant
app.component('formulaire', {
    data() {
        return {
            nom: ''
        };
    },
    template: `
        <input v-model="nom" placeholder="Entrez votre nom"/>
        <button @click="envoyer">Envoyer</button>
    `,
    methods: {
        envoyer() {
            this.$emit('form-submitted', this.nom);
        }
    }
});

// Composant parent
<formulaire @form-submitted='handleSubmission'></formulaire>

// Méthode du composant parent
methods: {
    handleSubmission(nom) {
        console.log('Nom reçu:', nom);
    }
}
        

Bonnes Pratiques

  • Utilisez des noms d'événements descriptifs et significatifs.
  • Centralisez la gestion des événements dans le parent pour éviter une logique dispersée.
  • Évitez d'émettre trop d'événements, ce qui pourrait rendre le flux de données difficile à suivre.

Applications Pratiques

  • Gérer les interactions utilisateur dans un formulaire ou une modale.
  • Notifier le parent lorsque des données sont modifiées dans un enfant.
  • Créer des composants interactifs comme des sliders ou des menus.

Résumé

  • Les Custom Events permettent la communication des enfants vers les parents.
  • Ils utilisent this.$emit dans les enfants et @nom-evenement dans les parents.
  • Ils sont essentiels pour maintenir un flux de données unidirectionnel.

Slots

Les slots permettent de passer du contenu HTML d'un composant parent à un composant enfant. Ils offrent une grande flexibilité pour créer des composants réutilisables tout en permettant aux parents de personnaliser le contenu affiché.

Qu'est-ce qu'un Slot ?

Un slot agit comme un point d'insertion dans le template d'un composant. Le contenu transmis par le parent remplace le slot défini dans le composant enfant.

Utilisation de Base des Slots

Voici un exemple simple de définition et d'utilisation d'un slot :

// Composant enfant
app.component('card', {
    template: `
        <div class="card">
            <slot>Contenu par défaut</slot>
        </div>
    `
});

// Composant parent
<card>
    <p>Contenu personnalisé</p>
</card>
        

Dans cet exemple :

  • Le composant enfant utilise un <slot> pour définir une zone où le contenu personnalisé sera inséré.
  • Si aucun contenu n'est fourni par le parent, le texte "Contenu par défaut" sera affiché.

Nommer les Slots

Vous pouvez nommer des slots pour créer plusieurs zones de contenu personnalisables.

// Composant enfant
app.component('layout', {
    template: `
        <header><slot name="header">Header par défaut</slot></header>
        <main><slot>Contenu principal par défaut</slot></main>
        <footer><slot name="footer">Footer par défaut</slot></footer>
    `
});

// Composant parent
<layout>
    <template v-slot:header>
        <h1>Mon Header</h1>
    </template>
    <p>Contenu principal</p>
    <template v-slot:footer>
        <p>Mon Footer</p>
    </template>
</layout>
        

Slots Scoped (À Portée)

Les slots scoped permettent au composant enfant de transmettre des données au contenu inséré par le parent.

// Composant enfant
app.component('liste', {
    data() {
        return {
            items: ['Item 1', 'Item 2', 'Item 3']
        };
    },
    template: `
        <ul>
            <li v-for="(item, index) in items" :key="index">
                <slot :item="item">{{ item }}</slot>
            </li>
        </ul>
    `
});

// Composant parent
<liste>
    <template v-slot="{ item }">
        <strong>{{ item }}</strong>
    </template>
</liste>
        

Ici :

  • Le composant enfant passe les données item au parent via le slot scoped.
  • Le parent personnalise l'affichage des éléments de la liste en utilisant ces données.

Bonnes Pratiques

  • Utilisez les slots pour personnaliser les composants tout en gardant leur logique intacte.
  • Nommer les slots clairement pour faciliter leur compréhension et leur utilisation.
  • Privilégiez les slots scoped pour transmettre des données des enfants vers les parents.

Applications Pratiques

  • Créer des layouts dynamiques avec des slots nommés pour le header, le contenu principal et le footer.
  • Construire des composants réutilisables comme des tableaux ou des listes personnalisables.
  • Gérer des vues complexes tout en maintenant une séparation claire des responsabilités.

Résumé

  • Les slots permettent de personnaliser le contenu des composants enfants.
  • Les slots nommés et scoped augmentent la flexibilité pour des composants complexes.
  • Ils sont essentiels pour créer des applications modulaires et réutilisables.

Dynamic Components

Les Dynamic Components permettent de basculer entre différents composants dynamiquement tout en conservant leur état. Cela est utile pour les scénarios où le contenu ou les fonctionnalités affichés changent en fonction des besoins utilisateur ou des événements.

Pourquoi Utiliser des Composants Dynamiques ?

Imaginez une interface utilisateur où des onglets, des étapes de formulaire ou des vues différentes doivent être affichés. Les composants dynamiques permettent de gérer ces scénarios tout en réduisant le code redondant et en améliorant la réutilisation.

Utilisation Basique

Vue.js fournit la balise <component> pour rendre des composants dynamiquement. Voici un exemple :

// Composants définis
app.component('composant-a', {
    template: '<div>Ceci est le Composant A</div>'
});
app.component('composant-b', {
    template: '<div>Ceci est le Composant B</div>'
});

// Utilisation dans le composant parent
<div>
    <button @click="composantActif = 'composant-a'">Afficher A</button>
    <button @click="composantActif = 'composant-b'">Afficher B</button>
    <component :is="composantActif"></component>
</div>
        

Dans cet exemple :

  • Les composants composant-a et composant-b sont définis.
  • La balise <component> bascule dynamiquement entre les composants en fonction de la variable composantActif.

Conservation de l'État avec keep-alive

Lors de l'utilisation de composants dynamiques, les instances sont recréées par défaut lors du changement. Si vous souhaitez conserver leur état, utilisez la directive keep-alive :

<keep-alive>
    <component :is="composantActif"></component>
</keep-alive>
        

Cela est utile pour préserver l'état des formulaires, des données ou des interactions utilisateur lorsque vous revenez à un composant précédent.

Utilisation Avancée

Vous pouvez charger des composants dynamiques de manière asynchrone pour améliorer les performances. Voici un exemple :

// Chargement asynchrone
app.component('composant-dynamique', () => import('./ComposantDynamique.vue'));

// Utilisation
<component :is="composantDynamique"></component>
        

Bonnes Pratiques

  • Utilisez des noms de composants clairs et descriptifs pour faciliter le suivi des composants dynamiques.
  • Employez keep-alive uniquement lorsque la conservation de l'état est nécessaire.
  • Chargez les composants dynamiquement pour réduire la taille initiale du bundle de l'application.

Applications Pratiques

  • Création de systèmes de navigation à onglets dynamiques.
  • Gestion de formulaires multi-étapes où chaque étape est un composant différent.
  • Affichage de différentes vues dans une seule section en fonction de l'état de l'application.

Résumé

  • Les composants dynamiques permettent de basculer entre différentes vues ou fonctionnalités de manière fluide.
  • La balise <component> est utilisée avec la directive :is pour afficher dynamiquement des composants.
  • Utilisez keep-alive pour conserver l'état et les données des composants.

Render Functions

Les Render Functions permettent de générer dynamiquement du contenu HTML dans un composant Vue.js en utilisant JavaScript. Contrairement aux templates, elles offrent une flexibilité accrue pour créer des structures dynamiques complexes.

Pourquoi Utiliser des Render Functions ?

Les templates Vue.js couvrent la plupart des cas d'utilisation. Cependant, les Render Functions deviennent utiles dans les situations suivantes :

  • Génération de structures HTML dynamiques qui dépendent fortement de la logique.
  • Réutilisation de structures complexes ou conditionnelles non gérables avec les templates.
  • Création de bibliothèques de composants où une flexibilité maximale est requise.

Syntaxe de Base

Une Render Function retourne un arbre d'éléments virtuels (VNode) représentant la structure HTML à afficher :

// Composant avec une Render Function
app.component('custom-render', {
    render() {
        return Vue.h(
            'div', 
            { class: 'custom-class' },
            'Ceci est généré par une Render Function.'
        );
    }
});
        

Ici :

  • Vue.h est utilisé pour créer des éléments virtuels (VNode).
  • Le premier argument est le nom de la balise HTML.
  • Le second argument est un objet d'attributs ou de propriétés.
  • Le troisième argument est le contenu ou les enfants.

Render Functions avec des Données Dynamiques

Vous pouvez créer des Render Functions qui affichent des éléments dynamiquement en fonction des données du composant :

// Composant avec Render Function et données dynamiques
app.component('dynamic-list', {
    data() {
        return {
            items: ['Item 1', 'Item 2', 'Item 3']
        };
    },
    render() {
        return Vue.h(
            'ul',
            this.items.map(item =>
                Vue.h('li', item)
            )
        );
    }
});
        

Utilisation Avancée

Les Render Functions peuvent inclure une logique conditionnelle complexe :

// Composant avec logique conditionnelle
app.component('conditional-render', {
    data() {
        return {
            showText: true
        };
    },
    render() {
        return this.showText
            ? Vue.h('p', 'Texte affiché.')
            : Vue.h('p', 'Texte masqué.');
    }
});
        

Bonnes Pratiques

  • Utilisez les Render Functions uniquement lorsque les templates ne suffisent pas.
  • Préférez des fonctions claires et bien structurées pour éviter la complexité.
  • Combinez-les avec des slots pour plus de flexibilité.

Applications Pratiques

  • Création de bibliothèques de composants où la configuration et la personnalisation sont cruciales.
  • Génération d'arbres DOM complexes basés sur des données dynamiques.
  • Intégration avec des bibliothèques tierces nécessitant un contrôle précis du DOM.

Résumé

  • Les Render Functions permettent de générer dynamiquement du contenu HTML en JavaScript.
  • Utilisez Vue.h pour créer des éléments virtuels (VNode).
  • Privilégiez-les pour les scénarios complexes nécessitant une flexibilité maximale.

Functional Components

Les Functional Components sont des composants légers et stateless (sans état) dans Vue.js. Ils sont utilisés lorsque le composant ne gère pas son propre état ou cycle de vie, et qu'il se contente de recevoir des props pour générer un rendu.

Pourquoi Utiliser des Functional Components ?

Les Functional Components sont utiles dans les scénarios suivants :

  • Les composants ne nécessitent pas de cycle de vie.
  • Ils n'ont pas besoin d'accès à des données locales ou à des méthodes de l'instance.
  • Vous souhaitez améliorer les performances pour des composants simples.

Création d'un Functional Component

Pour créer un composant fonctionnel, utilisez la propriété functional et fournissez une fonction de rendu :

// Création d'un composant fonctionnel
app.component('functional-button', {
    functional: true,
    props: {
        label: {
            type: String,
            required: true
        }
    },
    render(h, context) {
        return h(
            'button', 
            {
                class: 'btn btn-primary',
                on: context.listeners
            }, 
            context.props.label
        );
    }
});
        

Ici :

  • h est une fonction de rendu pour créer des éléments virtuels (VNode).
  • context.props contient les props passées au composant.
  • context.listeners permet de transmettre les événements du parent à l'enfant.

Utilisation

Un composant fonctionnel peut être utilisé comme un composant classique dans le template :

<functional-button label="Cliquez ici" @click="handleClick"></functional-button>
        

Avantages et Limitations

Avantages :

  • Performances améliorées grâce à l'absence d'instance de composant.
  • Plus léger et plus rapide à créer.
  • Convient pour des composants purement décoratifs ou de présentation.

Limitations :

  • Pas de gestion de l'état local.
  • Pas de cycle de vie des composants.
  • Moins adapté pour des scénarios complexes.

Applications Pratiques

  • Création de composants UI simples comme des boutons, des étiquettes ou des badges.
  • Utilisation dans des bibliothèques où les composants doivent être très performants.
  • Composants qui ne nécessitent que des props et des événements.

Résumé

  • Les Functional Components sont stateless et optimisés pour les performances.
  • Ils utilisent une fonction de rendu pour générer leur contenu.
  • Privilégiez-les pour des composants simples et légers.

Functional Components

Les Functional Components sont des composants légers et stateless (sans état) dans Vue.js. Ils sont utilisés lorsque le composant ne gère pas son propre état ou cycle de vie, et qu'il se contente de recevoir des props pour générer un rendu.

Pourquoi Utiliser des Functional Components ?

Les Functional Components sont utiles dans les scénarios suivants :

  • Les composants ne nécessitent pas de cycle de vie.
  • Ils n'ont pas besoin d'accès à des données locales ou à des méthodes de l'instance.
  • Vous souhaitez améliorer les performances pour des composants simples.

Création d'un Functional Component

Pour créer un composant fonctionnel, utilisez la propriété functional et fournissez une fonction de rendu :

// Création d'un composant fonctionnel
app.component('functional-button', {
    functional: true,
    props: {
        label: {
            type: String,
            required: true
        }
    },
    render(h, context) {
        return h(
            'button', 
            {
                class: 'btn btn-primary',
                on: context.listeners
            }, 
            context.props.label
        );
    }
});
        

Ici :

  • h est une fonction de rendu pour créer des éléments virtuels (VNode).
  • context.props contient les props passées au composant.
  • context.listeners permet de transmettre les événements du parent à l'enfant.

Utilisation

Un composant fonctionnel peut être utilisé comme un composant classique dans le template :

<functional-button label="Cliquez ici" @click="handleClick"></functional-button>
        

Avantages et Limitations

Avantages :

  • Performances améliorées grâce à l'absence d'instance de composant.
  • Plus léger et plus rapide à créer.
  • Convient pour des composants purement décoratifs ou de présentation.

Limitations :

  • Pas de gestion de l'état local.
  • Pas de cycle de vie des composants.
  • Moins adapté pour des scénarios complexes.

Applications Pratiques

  • Création de composants UI simples comme des boutons, des étiquettes ou des badges.
  • Utilisation dans des bibliothèques où les composants doivent être très performants.
  • Composants qui ne nécessitent que des props et des événements.

Résumé

  • Les Functional Components sont stateless et optimisés pour les performances.
  • Ils utilisent une fonction de rendu pour générer leur contenu.
  • Privilégiez-les pour des composants simples et légers.

reactive()

La méthode reactive() est utilisée pour créer un objet réactif en Vue.js. Elle transforme un objet JavaScript ordinaire en un objet réactif, ce qui signifie que toute modification des propriétés de cet objet sera détectée automatiquement par Vue et entraînera une mise à jour de l'interface utilisateur.

Pourquoi Utiliser reactive() ?

reactive() est particulièrement utile lorsque vous devez suivre les modifications sur plusieurs propriétés d'un objet ou lorsque vous travaillez avec des structures de données complexes comme des tableaux ou des objets imbriqués.

Exemple de Base

Voici comment utiliser reactive() :

// Création d'un objet réactif
import { reactive } from 'vue';

const state = reactive({
    compteur: 0,
    message: 'Bonjour Vue.js !'
});

// Modification des propriétés
state.compteur++;
state.message = 'Bonjour Reactivity!';
    

Utilisation dans un Composant

reactive() est souvent utilisé dans la fonction setup() des composants Vue.js pour définir des objets réactifs :

// Composant utilisant reactive()
import { defineComponent, reactive } from 'vue';

export default defineComponent({
    setup() {
        const state = reactive({
            compteur: 0,
            message: 'Cliquez sur le bouton'
        });

        // Méthode pour modifier les données
        const incrementer = () => {
            state.compteur++;
        };

        return { state, incrementer };
    },
    template: `
        <div>
            <p>{{ state.message }}: {{ state.compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Limites de reactive()

  • Imbrications : Toutes les propriétés imbriquées deviennent également réactives.
  • Type non pris en charge : reactive() ne peut pas rendre les primitifs (string, number, etc.) réactifs. Utilisez ref() pour cela.

Travailler avec des Objets Imbriqués

Les propriétés imbriquées d'un objet réactif sont également réactives, ce qui signifie que toute modification de leurs valeurs sera suivie automatiquement :

// Objet avec des propriétés imbriquées
const state = reactive({
    utilisateur: {
        nom: 'Jean',
        age: 25
    }
});

// Modification de la propriété imbriquée
state.utilisateur.age = 26;
    

Bonnes Pratiques

  • Utilisez reactive() pour des structures complexes ou des objets avec plusieurs propriétés.
  • Privilégiez des noms de propriétés descriptifs pour améliorer la lisibilité.
  • Combinez reactive() avec des méthodes pour encapsuler la logique de modification.

Applications Pratiques

  • Suivi des états dans des formulaires complexes.
  • Gestion des objets de configuration ou des modèles de données.
  • Création de tableaux réactifs pour afficher des listes interactives.

Résumé

  • reactive() rend un objet JavaScript réactif, permettant à Vue de détecter et de réagir aux modifications.
  • Idéal pour les structures de données complexes ou les objets imbriqués.
  • Ne prend pas en charge les valeurs primitives, utilisez ref() dans ces cas.

ref()

La méthode ref() permet de créer des valeurs réactives basées sur des primitives (string, number, boolean, etc.) ou des objets simples. Contrairement à reactive(), elle s’utilise principalement pour gérer une seule valeur réactive à la fois.

Pourquoi Utiliser ref() ?

ref() est idéal pour suivre une seule valeur ou lorsque vous travaillez avec des types primitifs. C'est aussi un outil clé dans le système de réactivité de Vue 3.

Exemple de Base

Voici un exemple simple pour comprendre comment utiliser ref() :

// Importation de ref
import { ref } from 'vue';

// Création d'une valeur réactive
const compteur = ref(0);

// Modification de la valeur
compteur.value++;
console.log(compteur.value); // Affiche 1
    

Utilisation dans un Composant

ref() est souvent utilisé dans la fonction setup() des composants Vue :

// Exemple dans un composant
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
        const message = ref('Bonjour Vue.js!');
        const compteur = ref(0);

        // Méthode pour incrémenter
        const incrementer = () => {
            compteur.value++;
        };

        return { message, compteur, incrementer };
    },
    template: `
        <div>
            <p>{{ message }}</p>
            <p>Compteur: {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Travail avec des Objets et des Tableaux

Bien que ref() puisse être utilisé avec des objets ou des tableaux, il est souvent préférable d'utiliser reactive(). Cependant, voici comment cela fonctionne :

// Tableau réactif
const liste = ref([1, 2, 3]);

// Ajout d'un élément
liste.value.push(4);
console.log(liste.value); // Affiche [1, 2, 3, 4]
    

Différence entre ref() et reactive()

Bien qu'ils soient similaires dans leur utilisation, voici les principales différences :

  • ref() est idéal pour une seule valeur ou une primitive.
  • reactive() est préférable pour des objets ou des structures de données complexes.
  • ref() nécessite d'accéder à la propriété .value pour lire ou modifier sa valeur.

Bonnes Pratiques

  • Utilisez ref() pour des valeurs primitives ou des objets simples.
  • Préférez reactive() pour des structures complexes imbriquées.
  • Combinez ref() et reactive() pour gérer des scénarios mixtes.

Applications Pratiques

  • Gestion d'une valeur de formulaire, comme un champ de texte.
  • Suivi de compteurs ou de statuts simples.
  • Suivi de la visibilité d'une modale avec un boolean (true/false).

Résumé

  • ref() rend une valeur primitive ou simple réactive.
  • Utilisez .value pour accéder ou modifier la valeur.
  • Combinez-le avec reactive() pour des scénarios plus complexes.

toRefs()

La méthode toRefs() est utilisée pour convertir les propriétés d'un objet réactif en références individuelles réactives (ref). Elle permet d’accéder directement aux propriétés d’un objet réactif tout en conservant leur réactivité.

Pourquoi Utiliser toRefs() ?

Lorsqu’un objet réactif est déstructuré (via l’opérateur de déstructuration), les propriétés perdent leur réactivité. toRefs() résout ce problème en transformant chaque propriété en une référence réactive.

Exemple de Base

Voici un exemple montrant comment toRefs() peut être utilisé :

// Importation de reactive et toRefs
import { reactive, toRefs } from 'vue';

// Création d'un objet réactif
const state = reactive({
    nom: 'Jean',
    age: 25
});

// Conversion des propriétés en refs
const { nom, age } = toRefs(state);

// Modification de la propriété réactive
nom.value = 'Marie'; // Met à jour state.nom
console.log(state.nom); // Affiche 'Marie'
    

Utilisation dans un Composant

Voici un exemple pratique dans un composant Vue :

// Exemple avec toRefs()
import { defineComponent, reactive, toRefs } from 'vue';

export default defineComponent({
    setup() {
        const state = reactive({
            compteur: 0,
            message: 'Cliquez pour incrémenter'
        });

        const incrementer = () => {
            state.compteur++;
        };

        // Déstructuration sécurisée avec toRefs
        return {
            ...toRefs(state),
            incrementer
        };
    },
    template: `
        <div>
            <p>{{ message }}</p>
            <p>Compteur: {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Quand Utiliser toRefs()

  • Pour la déstructuration : Si vous devez accéder aux propriétés d’un objet réactif individuellement après une déstructuration.
  • Pour passer des données réactives aux composants enfants : Vous pouvez transmettre des références réactives tout en maintenant leur réactivité.

Bonnes Pratiques

  • Utilisez toRefs() uniquement lorsque la déstructuration est nécessaire.
  • Privilégiez l'utilisation d'un objet réactif global si la déstructuration n'apporte pas de bénéfices.
  • Combinez toRefs() avec des méthodes pour encapsuler la logique et simplifier la maintenance.

Applications Pratiques

  • Passage de plusieurs données réactives à un composant enfant.
  • Gestion d’états complexes nécessitant des propriétés réactives accessibles individuellement.
  • Réduction des risques de perte de réactivité lors de l’utilisation de la déstructuration.

Résumé

  • toRefs() convertit les propriétés d’un objet réactif en références réactives individuelles.
  • Il est particulièrement utile lors de la déstructuration pour éviter la perte de réactivité.
  • Privilégiez son utilisation lorsque vous travaillez avec des structures complexes ou passez des données à des composants enfants.

shallowReactive()

shallowReactive est une fonction de Vue qui permet de créer un objet réactif mais limite la réactivité aux propriétés directes de l'objet. Les propriétés imbriquées ne sont pas réactives. Cela peut être utile pour des scénarios où les performances et un contrôle précis sur la réactivité sont requis.

Bonnes pratiques :

  • Utilisez shallowReactive pour des objets complexes où les propriétés imbriquées ne nécessitent pas de réactivité.
  • Combinez-le avec ref ou toRefs pour gérer les propriétés imbriquées si besoin.
  • Documentez les cas où vous utilisez shallowReactive pour éviter des comportements inattendus dans votre code.

Exemple simple

// Importation de shallowReactive
import { shallowReactive } from 'vue';

// Création d'un objet avec shallowReactive
const state = shallowReactive({
    utilisateur: {
        nom: 'Jean',
        age: 30
    }
});

// Modification d'une propriété directe
state.utilisateur = {
    nom: 'Alice',
    age: 25
};

// La propriété imbriquée ne sera pas réactive
state.utilisateur.nom = 'Bob';
        

Exemple pratique : Utilisation dans un composant

// Exemple : Utilisation de shallowReactive dans un composant Vue
import { defineComponent, shallowReactive } from 'vue';

export default defineComponent({
    setup() {
        const state = shallowReactive({
            utilisateur: {
                nom: 'Alice',
                age: 25
            },
            message: 'Bienvenue'
        });

        const changerUtilisateur = () => {
            // Propriété imbriquée : non réactive
            state.utilisateur.nom = 'Bob';
            // Propriété directe : réactive
            state.utilisateur = {
                nom: 'Charlie',
                age: 35
            };
        };

        return { state, changerUtilisateur };
    },
    template: `
        <div>
            <p>Nom : {{ state.utilisateur.nom }}</p>
            <p>Âge : {{ state.utilisateur.age }}</p>
            <button @click="changerUtilisateur">Changer l'utilisateur</button>
        </div>
    `
});
        

Pratiques courantes

Bien que `shallowReactive` ne soit pas aussi utilisé que `reactive`, il a des cas d'utilisation spécifiques. Voici quelques situations où il est fréquemment utilisé :

  • Stockage d'états simples : Par exemple, pour des configurations ou paramètres où les propriétés imbriquées ne nécessitent pas de réactivité.
  • Optimisation des performances : Si vous manipulez des objets lourds avec beaucoup de propriétés imbriquées inutilisées, comme des réponses d'API.
  • Composants isolés : Lorsque vous savez que la réactivité imbriquée n'est pas nécessaire pour un composant spécifique.

Bonnes pratiques

  • Documentez les endroits où vous utilisez `shallowReactive` pour que d'autres développeurs ne supposent pas que les propriétés imbriquées sont réactives.
  • Combinez `shallowReactive` avec `toRefs` si vous souhaitez rendre certaines propriétés réactives tout en gardant le contrôle.
  • Évitez d'utiliser `shallowReactive` si toutes les propriétés de l'objet nécessitent une réactivité. Préférez dans ce cas `reactive`.

Différences entre `shallowReactive` et `reactive`

Fonction Comportement Quand l'utiliser ?
reactive Rend réactives toutes les propriétés, y compris les propriétés imbriquées. Quand vous avez besoin de réactivité complète.
shallowReactive Rend réactives uniquement les propriétés directes. Pour optimiser les performances dans les objets complexes.

shallowRef()

Dans la Composition API de Vue.js, `shallowRef()` est une méthode qui permet de créer une référence réactive limitée uniquement au niveau supérieur de la donnée. Cela signifie que si la valeur de la référence est un objet ou un tableau, ses propriétés imbriquées ne seront pas suivies de manière réactive.

Cette méthode est utile dans les cas où une réactivité complète n'est pas nécessaire, par exemple pour des objets volumineux ou des structures de données complexes où seules les mises à jour de niveau supérieur doivent être surveillées. Elle est aussi idéale pour optimiser les performances dans les projets Vue.js.

Différence entre ref() et shallowRef()

Méthode Réactivité des propriétés imbriquées ? Utilisation
ref() Oui Pour des objets où chaque modification interne doit être suivie.
shallowRef() Non Pour des structures volumineuses ou des cas où seule la racine doit être réactive.

Syntaxe

// Importation de shallowRef
import { shallowRef } from 'vue';

// Création d'une référence réactive limitée
const state = shallowRef({
    utilisateur: {
        nom: 'Jean',
        age: 25
    }
});

// Mise à jour réactive
state.value = {
    utilisateur: { nom: 'Alice', age: 30 }
};

// Non réactif : modification interne
state.value.utilisateur.nom = 'Bob'; // Aucun effet réactif
            

Pratiques Courantes

1. Utilisation basique

// Importation de shallowRef
import { shallowRef } from 'vue';

// Exemple avec des données imbriquées
const state = shallowRef({
    message: 'Bonjour Vue.js!',
    nested: { key: 'valeur' }
});

// Réactif
state.value.message = 'Bonjour shallowRef!';

// Non réactif
state.value.nested.key = 'Nouvelle valeur'; // Aucun effet réactif
console.log(state.value.nested.key); // Mise à jour directe
            

2. Exemple dans un composant Vue

// Exemple dans un composant Vue
import { defineComponent, shallowRef } from 'vue';

export default defineComponent({
    setup() {
        // Déclaration d'une référence
        const state = shallowRef({
            compteur: 0,
            message: 'Cliquez sur le bouton'
        });

        // Méthode pour incrémenter
        const incrementer = () => {
            state.value.compteur++;
        };

        return { state, incrementer };
    },
    template: `
        <div>
            <p>{{ state.message }}</p>
            <p>Compteur: {{ state.compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
            

Bonnes Pratiques

  • Utilisez shallowRef() pour des données volumineuses ou complexes où seule la valeur racine doit être suivie.
  • Si vous avez besoin d'une réactivité complète, préférez ref() ou reactive().
  • Combinez avec des watchers si vous devez suivre manuellement les modifications internes.
  • Évitez d'utiliser shallowRef() pour des données nécessitant une gestion complexe de leurs sous-propriétés.

Scénarios Réels

Voici des cas réels où shallowRef() est utile :

  • Lorsque vous travaillez avec une bibliothèque externe qui gère ses propres données imbriquées.
  • Pour des structures de données volumineuses comme des graphiques ou des arbres où seules les mises à jour de haut niveau comptent.
  • Pour améliorer les performances dans des environnements critiques.

Vue Router : Router Setup

Vue Router est une bibliothèque officielle de Vue.js utilisée pour gérer la navigation entre différentes pages ou vues d'une application. Il est essentiel pour la création de SPA (Single Page Applications), où la navigation est gérée sans recharger la page.

Pourquoi utiliser Vue Router :
  • Gestion dynamique des routes.
  • Possibilité de passer des paramètres aux routes.
  • Navigation avec historique du navigateur.
  • Gestion des routes protégées (authentification).

Installation et Configuration de Base

Pour commencer à utiliser Vue Router, vous devez l'installer et configurer les routes de votre application. Voici les étapes nécessaires.

Étape 1 : Installation de Vue Router

// Commande pour installer Vue Router
npm install vue-router
        

Étape 2 : Structure de Projet

Assurez-vous que votre projet a une structure similaire à celle-ci :

// Structure typique d'un projet Vue avec Vue Router
my-vue-project/
├── src/
│   ├── components/
│   │   ├── Home.vue
│   │   ├── About.vue
│   ├── router/
│   │   ├── index.js
│   ├── App.vue
│   ├── main.js
        

Étape 3 : Configuration du Fichier Router

Créez un fichier nommé index.js dans le dossier src/router :

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';

// Importation des composants
import Home from '../components/Home.vue';
import About from '../components/About.vue';

// Définition des routes
const routes = [
    {
        path: '/',
        name: 'Home',
        component: Home
    },
    {
        path: '/about',
        name: 'About',
        component: About
    }
];

// Création de l'instance du router
const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router;
        

Étape 4 : Intégration de Vue Router

Ajoutez l'instance de router à votre application dans le fichier main.js :

// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // Importation du router

// Création de l'application avec le router
createApp(App).use(router).mount('#app');
        

Étape 5 : Ajout de Liens de Navigation

Utilisez le composant <router-link> pour naviguer entre les pages :

// src/App.vue
<template>
    <div>
        <nav>
            <router-link to='/'>Accueil</router-link>
            <router-link to='/about'>À Propos</router-link>
        </nav>
        <router-view></router-view> // Rendu des pages
    </div>
</template>
        

Résultat Final

Une fois configuré, vous pouvez naviguer entre les pages Home et About sans recharger la page.

Bonnes Pratiques

  • Utilisez des noms descriptifs pour vos routes (ex. : name: 'Home').
  • Organisez vos composants dans des dossiers clairs (/components, /views, etc.).
  • Activez le mode strict pour éviter les erreurs liées à des routes mal définies.
  • Privilégiez l'utilisation de lazy loading pour les composants afin d'améliorer les performances.
  • Gérez les erreurs de navigation à l'aide de beforeEach et onError.

Pratiques Courantes

  • Ajouter des paramètres aux routes pour passer des données spécifiques.
  • Protéger certaines routes avec des middlewares (authentification).
  • Utiliser des routes imbriquées pour structurer des sections complexes d'une application.

Vue Router : Route Params

Les **paramètres de route** dans Vue Router permettent de capturer des valeurs dynamiques à partir de l'URL. Ces valeurs rendent vos applications plus dynamiques, modulables et interconnectées. Par exemple, une URL comme /user/123 peut être utilisée pour afficher les détails d'un utilisateur avec l'identifiant 123.

Les paramètres de route sont définis dans le chemin avec un préfixe :. Une fois configurés, ils deviennent accessibles à l'intérieur de vos composants via l'objet $route.params.

Définir des Routes Dynamiques

Une route dynamique est définie en utilisant un chemin contenant des paramètres préfixés par :. Voici quelques exemples typiques :

Chemin Description Exemple d'URL Valeur des Paramètres
/user/:id Route avec un paramètre unique. /user/123 { id: '123' }
/product/:category/:id Route imbriquée pour une catégorie et un produit. /product/electronics/42 { category: 'electronics', id: '42' }
/blog/:slug Route utilisant un identifiant de type "slug". /blog/vue-router-intro { slug: 'vue-router-intro' }

Routes Dynamiques Imbriquées

Les routes imbriquées sont idéales pour les structures hiérarchiques, comme des utilisateurs ayant plusieurs publications. Les paramètres peuvent être définis à plusieurs niveaux.

// Configuration d'une route imbriquée
const routes = [
    {
        path: '/user/:userId/post/:postId',
        component: PostDetails
    }
];

// Exemple d'URL
// /user/1/post/42 correspond à { userId: '1', postId: '42' }
        

Accéder aux Paramètres de Route

Les paramètres de route sont disponibles dans l'objet $route.params. Utilisez-les directement dans vos composants pour adapter l'affichage.

// Composant User.vue
export default {
    setup() {
        const userId = $route.params.id;

        return { userId };
    },
    template: `
        <div>
            <p>Utilisateur ID : {{ userId }}</p>
        </div>
    `
};
        

Paramètres Facultatifs

Les paramètres peuvent être rendus facultatifs en ajoutant un point d'interrogation ? après leur nom.

// Exemple de route avec paramètre facultatif
const routes = [
    {
        path: '/user/:id?',
        component: User
    }
];

// /user/ correspond à { id: undefined }
// /user/123 correspond à { id: '123' }
        

Valider et Transformer les Paramètres

Utilisez des hooks comme beforeEnter pour valider ou transformer les paramètres avant de charger le composant. Cela permet de gérer des cas comme une redirection en cas de données invalides.

// Valider un paramètre avant de charger la route
const routes = [
    {
        path: '/user/:id',
        component: User,
        beforeEnter: (to, from, next) => {
            // Vérifie si l'ID est numérique
            if (isNaN(+to.params.id)) {
                next('/error');
            } else {
                next();
            }
        }
    }
];
        

Bonnes Pratiques

  • Validez toujours les paramètres de route pour éviter des comportements inattendus.
  • Créez des noms de paramètres explicites pour améliorer la lisibilité de vos routes.
  • Évitez de surcharger vos composants avec des responsabilités liées aux routes.
  • Gérez les erreurs, comme des paramètres manquants ou invalides, en redirigeant vers une page d'erreur dédiée.

Pratiques Courantes

  • Afficher un profil utilisateur basé sur un identifiant unique.
  • Créer des pages produits pour chaque catégorie et chaque produit individuel.
  • Charger dynamiquement des données d'une API en fonction des paramètres de l'URL.
  • Implémenter des fonctionnalités avancées comme des filtres basés sur les paramètres d'URL.

Vue Router : Route Guards

Les **Route Guards** (gardiens de route) sont des fonctions intermédiaires qui s’exécutent avant qu’une route ne soit validée. Ils permettent de contrôler l'accès aux routes, comme vérifier si un utilisateur est authentifié ou si des données sont correctement chargées avant d’afficher une page.

Vue Router fournit plusieurs types de gardiens de route :

  • Global : Gardiens s’appliquant à toutes les routes.
  • Par route : Spécifiques à une route donnée.
  • Dans le composant : Définis dans les composants Vue eux-mêmes.

Gardiens de Route Globaux

Les gardiens globaux interceptent toutes les transitions de route dans votre application.

// Exemple de guard global avant la navigation
router.beforeEach((to, from, next) => {
    // Vérifie si la route nécessite une authentification
    if (to.meta.requiresAuth && !isAuthenticated) {
        next('/login'); // Redirige vers la page de connexion
    } else {
        next(); // Continue vers la route
    }
});
        

Gardiens de Route au Niveau de la Route

Ces gardiens sont définis dans l'objet route, généralement pour valider ou transformer des paramètres avant de charger un composant.

// Exemple de guard par route
const routes = [
    {
        path: '/dashboard',
        component: Dashboard,
        meta: { requiresAuth: true },
        beforeEnter: (to, from, next) => {
            if (!isAuthenticated) {
                next('/login');
            } else {
                next();
            }
        }
    }
];
        

Gardiens de Route dans les Composants

Ces gardiens sont définis directement dans les composants Vue en utilisant les hooks beforeRouteEnter, beforeRouteUpdate et beforeRouteLeave.

// Exemple dans un composant
export default {
    methods: {
        fetchData() {
            console.log('Chargement des données');
        }
    },
    beforeRouteEnter(to, from, next) {
        // Charge les données avant d'entrer dans la route
        next(async (vm) => {
            await vm.fetchData();
        });
    },
    beforeRouteLeave(to, from, next) {
        // Avertit avant de quitter la route
        if (confirm('Êtes-vous sûr de vouloir quitter cette page ?')) {
            next();
        } else {
            next(false);
        }
    }
};
        

Bonnes Pratiques

  • Utilisez des meta propriétés pour ajouter des informations sur les routes (par exemple requiresAuth).
  • Évitez de surcharger vos gardiens de route avec trop de logique.
  • Préférez les gardiens globaux pour des règles générales, et les gardiens par route pour des validations spécifiques.
  • Gérez les redirections de manière explicite pour améliorer l'expérience utilisateur.
  • Testez vos gardiens avec des scénarios comme un utilisateur non authentifié ou des paramètres manquants.

Pratiques Courantes

  • Vérifier si un utilisateur est connecté avant d'accéder à des pages sensibles comme un tableau de bord.
  • Charger des données nécessaires dans un composant avant qu'il ne soit rendu.
  • Protéger des routes contre des utilisateurs non autorisés.
  • Afficher des messages de confirmation avant de quitter une page contenant des modifications non enregistrées.

Vue Router : Nested Routes (Routes Imbriquées)

Les **Nested Routes** (routes imbriquées) permettent de créer une hiérarchie entre les routes et leurs enfants. Elles sont particulièrement utiles pour organiser les pages ayant une structure parent-enfant, comme un tableau de bord avec des sous-sections ou un site avec des catégories et des sous-catégories.

Les Nested Routes permettent :

  • Une navigation hiérarchique intuitive.
  • Un rendu de composants enfants dans des composants parents via les balises <router-view>.
  • Une meilleure organisation des routes pour des applications complexes.

Configuration des Routes Imbriquées

Pour configurer des routes imbriquées, utilisez la propriété children dans les objets de définition des routes.

// Configuration de routes imbriquées
const routes = [
    {
        path: '/dashboard',
        component: Dashboard,
        children: [
            {
                path: 'overview',
                component: Overview
            },
            {
                path: 'settings',
                component: Settings
            }
        ]
    }
];
        

Exemple de Routes Imbriquées

// Exemple de composant parent
export default {
    template: `
        <div>
            <h1>Tableau de Bord</h1>
            <router-view /> // Composant enfant sera rendu ici
        </div>
    `
};
        
// Exemple de composant enfant
export default {
    template: `
        <div>
            <h2>Aperçu</h2>
            <p>Contenu de la section Aperçu</p>
        </div>
    `
};
        

Navigation avec des Routes Imbriquées

Pour naviguer entre les routes enfants, utilisez les balises <router-link> avec des chemins relatifs.

// Exemple HTML pour naviguer entre les routes imbriquées
<div>
    <h1>Tableau de Bord</h1>
    <nav>
        <router-link to='overview'>Aperçu</router-link>
        <router-link to='settings'>Paramètres</router-link>
    </nav>
    <router-view></router-view>
</div>
        

Bonnes Pratiques

  • Organisez vos routes imbriquées pour refléter la structure de navigation de votre application.
  • Utilisez des noms clairs et descriptifs pour vos composants parent et enfant.
  • Évitez les chemins absolus dans les routes enfants, préférez les chemins relatifs.
  • Gardez vos composants parent aussi légers que possible. Placez la logique spécifique dans les composants enfants.

Pratiques Courantes

  • Créer des tableaux de bord avec plusieurs sous-sections (aperçu, paramètres, rapports, etc.).
  • Afficher des catégories et des sous-catégories dans une boutique en ligne.
  • Gérer des workflows complexes comme des formulaires multi-étapes.
  • Imbriquer des routes pour les forums ou blogs avec des pages pour les sujets et leurs commentaires.

Avantages des Routes Imbriquées

Avantage Description
Organisation Structure les routes de manière hiérarchique, facilitant la maintenance.
Rendu Dynamique Permet de rendre des composants enfants dynamiquement à l'intérieur des parents.
Clarté Améliore la clarté de la navigation pour les utilisateurs finaux.
Flexibilité S'adapte aux applications avec des interfaces complexes.

Introduction à Vuex

Vuex est une bibliothèque de gestion d'état spécialement conçue pour Vue.js. Elle suit un modèle centralisé, ce qui signifie que toutes les données partagées sont stockées dans un **store unique**. Ce modèle facilite la synchronisation des données entre les composants de l'application, surtout lorsque celle-ci devient complexe.

Pourquoi utiliser Vuex ?

  • Centralisation : Toutes les données partagées sont gérées dans un seul endroit.
  • Prévisibilité : L'état ne peut être modifié que par des mutations explicites, ce qui rend les changements traçables.
  • Réactivité : Les composants sont automatiquement mis à jour lorsque l'état change.
  • Outillage : Vuex offre une intégration avec Vue Devtools pour déboguer et suivre les changements de l'état.

Concepts Clés :

  • State : Représente les données partagées de l'application.
  • Mutations : Permettent de modifier l'état de manière prévisible.
  • Actions : Gèrent les opérations asynchrones avant de modifier l'état.
  • Getters : Calculent et exposent des dérivés de l'état.
  • Modules : Structurent le store pour les grandes applications.

Introduction à Vuex

**Vuex** est une bibliothèque officielle pour la gestion de l'état dans les applications Vue.js. Elle repose sur un modèle centralisé qui permet de gérer l'état global de l'application de manière prévisible et efficace. Vuex est particulièrement utile pour les applications de grande taille ou celles nécessitant un partage de données entre plusieurs composants.

Vuex repose sur les concepts suivants :

  • État (State) : Représente les données partagées entre les composants.
  • Getters : Permettent de lire et transformer l'état sans le modifier directement.
  • Mutations : Méthodes synchrones pour modifier l'état.
  • Actions : Permettent d'effectuer des opérations asynchrones avant d'appeler une mutation.
  • Modules : Divisent l'état et la logique en sections distinctes pour une meilleure organisation.

Pourquoi utiliser Vuex ?

  • Facilite la gestion de l'état dans des applications complexes.
  • Offre un modèle clair pour gérer les données et leurs mutations.
  • Permet de partager des données entre plusieurs composants sans avoir à passer par des props ou des événements.
  • Favorise une approche déclarative et prévisible pour la gestion de l'état.

Installation de Vuex

Installez Vuex dans votre projet à l'aide de npm ou yarn.

// Installation via npm
npm install vuex@next

// Installation via yarn
yarn add vuex@next
        

Configuration de Vuex

Après l'installation, configurez Vuex dans votre application en créant un store et en l'ajoutant à l'instance Vue.

// Importation de Vue et Vuex
import { createApp } from 'vue';
import { createStore } from 'vuex';
import App from './App.vue';

// Création du store Vuex
const store = createStore({
    state: {
        compteur: 0
    },
    mutations: {
        incrementer(state) {
            state.compteur++;
        }
    },
    actions: {
        incrementerContexte({ commit }) {
            commit('incrementer');
        }
    },
    getters: {
        compteurDouble(state) {
            return state.compteur * 2;
        }
    }
});

// Création de l'application Vue
const app = createApp(App);

// Ajout du store à l'application
app.use(store);

app.mount('#app');
        

Structure du Store Vuex

Concept Description Exemple
State Représente les données centralisées de l'application. state: { compteur: 0 }
Mutations Permettent de modifier l'état de manière synchrone. mutations: { incrementer(state) { state.compteur++ } }
Actions Permettent d'effectuer des opérations asynchrones. actions: { incrementerContexte({ commit }) { commit('incrementer') } }
Getters Permettent de lire et transformer l'état. getters: { compteurDouble(state) { return state.compteur * 2 } }

Bonnes Pratiques

  • Ne modifiez jamais directement l'état. Utilisez toujours les mutations.
  • Divisez le store en modules si l'application devient complexe.
  • Gardez vos actions simples et évitez de surcharger la logique dans les composants.
  • Utilisez les getters pour toute transformation ou calcul basé sur l'état.

Pratiques Courantes

  • Gérer l'authentification d'un utilisateur avec un état global.
  • Suivre les préférences utilisateur (thème, langue, etc.).
  • Centraliser les données d'un panier d'achat dans une boutique en ligne.
  • Partager les données entre des composants éloignés dans la hiérarchie.

State dans Vuex

Le state dans Vuex est une structure globale permettant de centraliser les données pour les partager facilement entre plusieurs composants. Cela simplifie la gestion des états complexes dans les applications Vue.js.

Qu'est-ce que le State ?

Concept Description Exemple
State Global Données centralisées accessibles depuis tous les composants. $store.state
Immutable Directement Le state ne doit pas être modifié directement. Utilisez des mutations. $store.commit('mutation')
Partage de Données Idéal pour partager des données entre des composants distants. Utilisateur, panier, configuration

Création d'un State

Le **state** est défini comme une propriété dans le store Vuex. Voici un exemple de définition :

// Création d'un store Vuex
import { createStore } from 'vuex';

const store = createStore({
    state: {
        compteur: 0,
        utilisateur: {
            nom: 'Alice',
            email: 'alice@example.com'
        }
    }
});

export default store;
        

Accès aux Données

Pour accéder aux données dans le state, utilisez this.$store.state depuis vos composants Vue. Voici un exemple simple :

<template>
    <div>
        <p>Compteur : {{ $store.state.compteur }}</p>
        <p>Nom : {{ $store.state.utilisateur.nom }}</p>
    </div>
</template>
        

Modifier le State

Pour modifier les données, utilisez des **mutations**. Cela permet de suivre toutes les modifications dans le store pour un meilleur débogage.

// Définir une mutation
const store = createStore({
    state: {
        compteur: 0
    },
    mutations: {
        incrementer(state) {
            state.compteur++;
        }
    }
});
        

Exemple d'utilisation dans un composant :

<template>
    <div>
        <p>Compteur : {{ $store.state.compteur }}</p>
        <button @click='$store.commit("incrementer")'>Incrémenter</button>
    </div>
</template>
        

Techniques Avancées

Voici quelques techniques pour travailler efficacement avec le state dans Vuex :

Technique Explication Exemple
Mutations et Actions Utilisez des actions pour les opérations asynchrones et des mutations pour modifier les données. this.$store.dispatch('actionName')
Modules Vuex Divisez le state en modules pour les grandes applications. store.moduleName.state
Persist State Utilisez des plugins pour sauvegarder le state dans le localStorage. vuex-persist

Cas Pratique : Gestion d'un Panier d'Achat

// Définir un store avec gestion de panier
const store = createStore({
    state: {
        panier: []
    },
    mutations: {
        ajouterArticle(state, article) {
            state.panier.push(article);
        },
        supprimerArticle(state, index) {
            state.panier.splice(index, 1);
        }
    }
});
        

Dans un composant Vue :

<template>
    <div>
        <ul>
            <li v-for='(article, index) in $store.state.panier' :key='index'>
                {{ article.nom }} - {{ article.prix }} €
                <button @click='$store.commit("supprimerArticle", index)'>Supprimer</button>
            </li>
        </ul>
    </div>
</template>
        

Bonnes Pratiques

  • Évitez de manipuler directement le state depuis les composants.
  • Utilisez les **mutations** pour suivre les modifications.
  • Modularisez votre store avec des modules pour simplifier la maintenance.
  • Privilégiez les actions pour les tâches complexes ou asynchrones.

Vuex : Getters

Théorie et Introduction

Dans Vuex, les getters jouent un rôle essentiel en tant que fonctions dérivées. Ils permettent de transformer, filtrer ou accéder facilement aux données présentes dans le state. Ils ressemblent aux propriétés calculées (computed) dans les composants Vue et sont utilisés pour encapsuler la logique qui manipule les données.

Utiliser des getters présente plusieurs avantages :

  • Centraliser les opérations répétitives dans le store.
  • Garder les composants simples en déléguant la logique complexe au store.
  • Optimiser les performances grâce au système de cache des getters.
À retenir : Les getters sont particulièrement utiles pour manipuler les données sous une forme transformée ou dérivée, comme :
  • Filtrer des listes selon des critères spécifiques.
  • Calculer des totaux ou des statistiques.
  • Créer des vues spécifiques sur le state sans le modifier.

Fonctionnement et Création

Les getters sont définis dans la section getters du store Vuex. Voici un aperçu de leur fonctionnement :

// Exemple basique de store avec getters
const store = createStore({
    state: {
        produits: [
            { nom: 'Produit A', prix: 100, actif: true },
            { nom: 'Produit B', prix: 200, actif: false }
        ]
    },
    getters: {
        produitsActifs(state) {
            return state.produits.filter(produit => produit.actif);
        },
        totalPrix(state) {
            return state.produits.reduce((total, produit) => total + produit.prix, 0);
        }
    }
});

// Accéder aux getters
store.getters.produitsActifs; // Liste des produits actifs
store.getters.totalPrix; // Total des prix
        

Avantages des Getters

Avantage Description Exemple
Réutilisabilité Permet de réutiliser une logique complexe dans différents composants. store.getters.produitsActifs
Mémoire Cache Optimisé pour éviter des calculs inutiles tant que les dépendances restent identiques. computed() similaire.
Lisibilité Centralise la logique dans le store, rendant le code plus lisible et maintenable. Encapsulation de filtres et transformations.

Utilisation Avancée

Les getters peuvent également retourner des fonctions pour permettre l’utilisation de paramètres. Cela les rend extrêmement flexibles pour des cas complexes.

// Exemple : Getter avec paramètres
const store = createStore({
    state: {
        produits: [
            { nom: 'Produit A', prix: 100 },
            { nom: 'Produit B', prix: 200 }
        ]
    },
    getters: {
        produitsAuDessusDe(state) {
            return (prixMinimum) => {
                return state.produits.filter(produit => produit.prix >= prixMinimum);
            };
        }
    }
});

// Appel du getter avec un paramètre
store.getters.produitsAuDessusDe(150); // Retourne Produit B
        

Bonnes Pratiques

  • Utilisez des noms explicites pour vos getters afin de décrire leur intention.
  • Centralisez toute logique complexe ou récurrente dans un getter plutôt que dans un composant.
  • Évitez de modifier directement le state dans un getter.
  • Testez vos getters séparément pour garantir leur bon fonctionnement.

Techniques Pratiques Courantes

Voici des exemples d'utilisations fréquentes des getters :

Technique Description Exemple
Calcul des Totaux Utilisez des getters pour calculer des totaux comme le prix total d'un panier. getters.totalPrix
Filtrage Dynamique Retournez une fonction pour filtrer selon des critères dynamiques. getters.produitsAuDessusDe
Combinaisons de Getters Combinez plusieurs getters pour des transformations complexes. getters.filtrésEtTriés

Exemple Complet

Voici un exemple combinant plusieurs concepts :

// Exemple : Filtrage et calcul de totaux
const store = createStore({
    state: {
        produits: [
            { nom: 'Produit A', prix: 100, categorie: 'Electronics' },
            { nom: 'Produit B', prix: 200, categorie: 'Furniture' }
        ]
    },
    getters: {
        produitsParCategorie(state) {
            return (categorie) => {
                return state.produits.filter(produit => produit.categorie === categorie);
            };
        },
        totalParCategorie(state, getters) {
            return (categorie) => {
                return getters.produitsParCategorie(categorie)
                    .reduce((total, produit) => total + produit.prix, 0);
            };
        }
    }
});

// Utilisation
store.getters.totalParCategorie('Electronics'); // Retourne 100
        

Vuex : Mutations

Théorie et Introduction

Les mutations dans Vuex sont le seul moyen officiel de modifier le state de manière synchrone. Elles assurent une traçabilité et une prévisibilité des changements en centralisant toutes les modifications du state.

Les mutations fonctionnent comme des méthodes que vous définissez dans le store et que vous appelez via commit. Chaque mutation reçoit en premier argument le state actuel du store.

Pourquoi utiliser des mutations ?
  • Garantir une gestion claire et centralisée des changements d'état.
  • Faciliter le débogage grâce aux outils comme Vue DevTools.
  • Éviter les modifications imprévues du state.

Syntaxe et Définition

Une mutation est définie dans la section mutations du store Vuex :

// Définition des mutations dans le store
const store = new Vuex.Store({
    state: {
        compteur: 0
    },
    mutations: {
        incrementer(state) {
            state.compteur++;
        },
        decrementer(state) {
            state.compteur--;
        },
        reset(state, valeurInitiale) {
            state.compteur = valeurInitiale;
        }
    }
});
    

Pour appeler une mutation, utilisez store.commit :

// Appel de mutations
store.commit('incrementer');
store.commit('decrementer');
store.commit('reset', 10);
    

Exemples Pratiques

Exemple 1 : Compteur avec Vuex

// Définition du store
const store = new Vuex.Store({
    state: {
        compteur: 0
    },
    mutations: {
        incrementer(state) {
            state.compteur++;
        }
    }
});

// Utilisation dans un composant Vue
const app = Vue.createApp({
    methods: {
        incrementer() {
            this.$store.commit('incrementer');
        }
    },
    computed: {
        compteur() {
            return this.$store.state.compteur;
        }
    },
    template: `
        <div>
            <p>Compteur : {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
app.use(store).mount('#app');
    

Exemple 2 : Ajout d'éléments à une liste

// Définition d'une mutation pour ajouter des produits
const store = new Vuex.Store({
    state: {
        panier: []
    },
    mutations: {
        ajouterProduit(state, produit) {
            state.panier.push(produit);
        }
    }
});

// Exemple d'utilisation
store.commit('ajouterProduit', { nom: 'Produit A', prix: 20 });
store.commit('ajouterProduit', { nom: 'Produit B', prix: 30 });

console.log(store.state.panier); // Affiche les produits ajoutés
    

Bonnes Pratiques

Cas d'Utilisation Courants

Cas Exemple Description
Mise à jour d'un compteur incrementer(state) Ajoute ou soustrait une valeur du compteur.
Ajout à une liste ajouterProduit(state, produit) Ajoute un élément à une liste (ex. : panier d'achat).
Réinitialisation reset(state) Réinitialise une valeur ou une structure.

En suivant ces bonnes pratiques, vous maintenez votre store Vuex clair, performant et facile à déboguer.

Vuex : Actions

Théorie et Introduction

Les actions dans Vuex sont utilisées pour effectuer des tâches asynchrones, comme récupérer des données depuis une API ou traiter une logique complexe avant de mettre à jour le state. Contrairement aux mutations, les actions ne modifient pas directement le state ; elles invoquent des mutations via commit.

En plus de permettre des opérations asynchrones, les actions offrent une structure claire pour séparer la logique métier des composants Vue.

À retenir :
  • Utilisez dispatch pour invoquer des actions, et non commit.
  • Une action peut appeler plusieurs mutations.
  • Les actions peuvent être chaînées grâce aux promesses retournées.

Syntaxe et Définition

Les actions sont définies dans la section actions du store et prennent un objet context comme premier paramètre, qui inclut des propriétés comme commit et state.

// Définition d'actions
const store = new Vuex.Store({
    state: {
        compteur: 0
    },
    mutations: {
        incrementer(state, valeur) {
            state.compteur += valeur;
        }
    },
    actions: {
        asyncIncrementer(context, valeur) {
            setTimeout(() => {
                context.commit('incrementer', valeur);
            }, 1000);
        }
    }
});
    

Exemples Pratiques

Exemple 1 : Incrémentation Asynchrone

// Appel d'une action
store.dispatch('asyncIncrementer', 5);

// Résultat après 1 seconde
console.log(store.state.compteur); // Affiche 5
    

Exemple 2 : Chargement de Données depuis une API

// Définition de l'action
const store = new Vuex.Store({
    state: {
        utilisateurs: []
    },
    mutations: {
        setUtilisateurs(state, utilisateurs) {
            state.utilisateurs = utilisateurs;
        }
    },
    actions: {
        async chargerUtilisateurs({ commit }) {
            try {
                const response = await fetch('https://api.example.com/utilisateurs');
                const data = await response.json();
                commit('setUtilisateurs', data);
            } catch (erreur) {
                console.error('Erreur lors du chargement des utilisateurs :', erreur);
            }
        }
    }
});
    

Exemple 3 : Actions Chaînées

// Chaînage des actions
store.dispatch('chargerUtilisateurs').then(() => {
    console.log('Utilisateurs chargés avec succès.');
}).catch((erreur) => {
    console.error('Erreur:', erreur);
});
    

Bonnes Pratiques

Cas d'Utilisation Courants

Cas Exemple Description
Récupération de données chargerUtilisateurs({ commit }) Récupère des données depuis une API et les stocke dans le state.
Incrémentation asynchrone asyncIncrementer(context, valeur) Met à jour le state après un délai ou une opération.
Chaînage d'actions store.dispatch('action1').then(() => store.dispatch('action2')) Exécute des actions de manière séquentielle.

En suivant ces pratiques, les actions garantissent une gestion efficace et maintenable des opérations asynchrones dans Vuex.

Vuex : Modules

Théorie et Introduction

Lorsqu'une application Vue.js devient de plus en plus complexe, le store Vuex peut rapidement devenir difficile à gérer. Les modules Vuex offrent une solution en permettant de diviser le store en sous-sections logiques et indépendantes. Chaque module peut contenir son propre state, ses getters, ses mutations et ses actions.

Les modules facilitent :

À retenir : Les modules permettent de :
  • Créer des structures hiérarchiques en imbriquant les modules.
  • Utiliser des espaces de noms pour isoler les actions et getters des modules.
  • Répartir les fonctionnalités selon des contextes spécifiques.

Syntaxe et Définition

Pour définir des modules, utilisez la propriété modules dans le store principal.

// Exemple d'un store avec des modules
const utilisateursModule = {
    state: {
        liste: []
    },
    mutations: {
        setUtilisateurs(state, utilisateurs) {
            state.liste = utilisateurs;
        }
    },
    actions: {
        async chargerUtilisateurs({ commit }) {
            const response = await fetch('https://api.example.com/utilisateurs');
            const data = await response.json();
            commit('setUtilisateurs', data);
        }
    },
    getters: {
        totalUtilisateurs(state) {
            return state.liste.length;
        }
    }
};

const produitsModule = {
    state: {
        liste: []
    },
    mutations: {
        setProduits(state, produits) {
            state.liste = produits;
        }
    },
    getters: {
        produitsDisponibles(state) {
            return state.liste.filter(produit => produit.stock > 0);
        }
    }
};

const store = new Vuex.Store({
    modules: {
        utilisateurs: utilisateursModule,
        produits: produitsModule
    }
});
    

Exemples Pratiques

Exemple 1 : Gestion des Utilisateurs

// Appel d'une action dans un module
store.dispatch('utilisateurs/chargerUtilisateurs');

// Accès à un getter
const total = store.getters['utilisateurs/totalUtilisateurs'];
console.log(total);
    

Exemple 2 : Gestion des Produits

// Accès aux produits disponibles
const disponibles = store.getters['produits/produitsDisponibles'];
console.log(disponibles);
    

Exemple 3 : Modules Imbriqués

// Exemple d'un module imbriqué
const commandesModule = {
    state: {
        commandes: []
    },
    modules: {
        historique: {
            state: {
                anciennesCommandes: []
            },
            mutations: {
                ajouterCommande(state, commande) {
                    state.anciennesCommandes.push(commande);
                }
            }
        }
    }
};

const store = new Vuex.Store({
    modules: {
        commandes: commandesModule
    }
});

store.commit('commandes/historique/ajouterCommande', 'Nouvelle commande');
    

Bonnes Pratiques

Cas d'Utilisation Courants

Cas Exemple Description
Gestion des utilisateurs utilisateurs/chargerUtilisateurs Charge les utilisateurs depuis une API et les stocke dans le module utilisateurs.
Gestion des produits produits/produitsDisponibles Filtre les produits en stock dans le module produits.
Imbrication de modules commandes/historique/ajouterCommande Ajoute une commande à l'historique dans un module imbriqué.

En structurant votre store Vuex avec des modules, vous rendez votre code plus lisible, maintenable et modulaire, ce qui facilite la collaboration sur des projets complexes.

Qu'est-ce que la Composition API ?

La Composition API est une nouvelle manière d'organiser et de structurer les composants dans Vue 3. Elle introduit une approche fonctionnelle pour définir le comportement et l'état des composants. Contrairement à l'Options API, où les propriétés comme data, methods, et computed sont séparées, la Composition API permet de regrouper logiquement les fonctionnalités dans des fonctions JavaScript.

Pourquoi utiliser la Composition API ?

La Composition API a été introduite pour résoudre plusieurs limitations de l'Options API dans Vue.js :

À retenir :
  • La Composition API ne remplace pas l'Options API ; elle est une alternative pour les développeurs qui préfèrent une approche plus flexible.
  • Elle est particulièrement utile dans les projets complexes ou pour les équipes qui souhaitent structurer leur code de manière modulaire.

Fonction setup()

Introduction

La fonction setup() est le cœur de la Composition API dans Vue 3. Elle remplace ou complète les options comme data, methods, et computed de l'Options API. Appelée avant le cycle de vie du composant, setup() initialise l'état réactif et fournit des méthodes ou des propriétés pour être utilisées dans le template.

Points clés :
  • Elle est appelée avant les hooks de cycle de vie comme created.
  • Le setup() doit renvoyer un objet contenant les propriétés et méthodes accessibles dans le template.
  • Permet une meilleure organisation logique dans le code.

Syntaxe de base

La fonction setup() prend deux arguments :

// Exemple de base de setup()
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup(props, context) {
        // Déclaration d'une valeur réactive
        const compteur = ref(0);

        // Méthode pour incrémenter
        const incrementer = () => {
            compteur.value++;
        };

        // Retourne les propriétés et méthodes au template
        return {
            compteur,
            incrementer
        };
    }
});
    

Exemple pratique

Voici un exemple pratique où setup() est utilisé pour gérer une valeur réactive et une méthode d'interaction avec un événement.

// Composant avec setup()
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
        // Déclaration d'une valeur réactive
        const message = ref('Bonjour Vue.js!');
        const compteur = ref(0);

        // Méthode pour incrémenter le compteur
        const incrementer = () => {
            compteur.value++;
        };

        return { message, compteur, incrementer };
    },
    template: `
        <div>
            <p>{{ message }}</p>
            <p>Compteur : {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Structure recommandée

Pour les projets complexes, il est recommandé d'organiser les données, les méthodes et les hooks en sections logiques :

// Organisation recommandée dans setup()
import { defineComponent, ref, reactive, onMounted } from 'vue';

export default defineComponent({
    setup() {
        // Données réactives
        const compteur = ref(0);
        const state = reactive({
            message: 'Hello Vue.js!',
            utilisateurs: []
        });

        // Méthodes
        const incrementer = () => compteur.value++;
        const chargerUtilisateurs = async () => {
            const response = await fetch('https://api.example.com/users');
            state.utilisateurs = await response.json();
        };

        // Hook de cycle de vie
        onMounted(() => {
            console.log('Composant monté');
            chargerUtilisateurs();
        });

        // Retour des données et méthodes
        return {
            compteur,
            state,
            incrementer
        };
    }
});
    

Bonnes pratiques

  • Organisez les données, méthodes et hooks en sections logiques dans setup().
  • Utilisez des noms descriptifs pour les variables et méthodes.
  • Minimisez la logique complexe dans setup() en la déléguant à des fonctions externes ou à des composables.
  • Préférez l'utilisation de reactive pour les objets imbriqués et de ref pour les valeurs primitives.
  • Évitez de retourner tout l'objet props pour limiter les modifications accidentelles.

Fonction reactive()

Introduction

La fonction reactive() de Vue 3 est utilisée pour créer des objets réactifs, c'est-à-dire des objets dont les modifications déclenchent automatiquement une mise à jour de l'interface utilisateur. Contrairement à ref(), qui est destiné aux valeurs primitives, reactive() est conçu pour les objets complexes tels que les tableaux et les objets imbriqués.

Points clés :
  • Convient pour gérer des structures complexes comme des objets ou des tableaux.
  • Les propriétés imbriquées dans un objet reactive sont également rendues réactives.
  • Les objets réactifs retournés par reactive() conservent leur forme d'origine (contrairement à ref).

Syntaxe et utilisation

La fonction reactive() prend un objet comme argument et renvoie une version réactive de cet objet.

// Création d'un objet réactif avec reactive()
import { reactive } from 'vue';

// Déclaration d'un état réactif
const state = reactive({
    compteur: 0,
    message: 'Bonjour Vue.js!'
});

// Modification des propriétés
state.compteur++;
state.message = 'Bonjour Reactivity!';
    

Exemple pratique

Voici un exemple d'utilisation de reactive() dans un composant Vue pour gérer des données complexes et imbriquées.

// Composant utilisant reactive()
import { defineComponent, reactive } from 'vue';

export default defineComponent({
    setup() {
        // État réactif
        const state = reactive({
            utilisateur: {
                nom: 'Jean',
                age: 30
            },
            compteur: 0
        });

        // Méthode pour modifier les données
        const incrementer = () => {
            state.compteur++;
        };

        return {
            state,
            incrementer
        };
    },
    template: `
        <div>
            <p>Nom : {{ state.utilisateur.nom }}</p>
            <p>Âge : {{ state.utilisateur.age }}</p>
            <p>Compteur : {{ state.compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Utilisation avec des objets imbriqués

Un des avantages de reactive() est qu'il rend réactives toutes les propriétés imbriquées de l'objet, ce qui est idéal pour gérer des états complexes.

// Exemple avec un objet imbriqué
import { reactive } from 'vue';

// Objet avec des propriétés imbriquées
const state = reactive({
    utilisateur: {
        nom: 'Alice',
        details: {
            age: 28,
            pays: 'France'
        }
    }
});

// Modification des propriétés imbriquées
state.utilisateur.details.age = 29;
    

Bonnes pratiques

  • Utilisez reactive() pour les objets et tableaux complexes, mais préférez ref() pour les valeurs primitives.
  • Évitez d'utiliser directement des structures profondes si vous ne les modifiez pas fréquemment. Les objets profondément imbriqués peuvent compliquer le débogage.
  • Utilisez des outils comme Vue Devtools pour visualiser et déboguer vos objets réactifs.
  • Si vous avez besoin de déstructurer des propriétés réactives, utilisez toRefs() pour éviter de perdre la réactivité.
  • Organisez vos données imbriquées en composant des objets plus simples, si possible, pour améliorer la lisibilité et la maintenabilité.

Pratiques courantes

Créer un tableau réactif : Les tableaux peuvent être directement encapsulés dans reactive(), ce qui permet de suivre les ajouts, suppressions et modifications.

// Exemple avec un tableau réactif
const state = reactive({
    liste: [1, 2, 3]
});

// Ajout d'un élément
state.liste.push(4);

// Suppression d'un élément
state.liste.pop();
    

En combinant reactive() avec d'autres fonctionnalités comme les hooks de cycle de vie et les composants enfants, vous pouvez structurer des applications performantes et maintenables.

Fonction ref()

Introduction

La fonction ref() est une des fonctionnalités fondamentales de la Composition API dans Vue 3. Elle est utilisée pour rendre une valeur réactive, qu'il s'agisse d'une valeur primitive comme un nombre ou une chaîne de caractères, ou d'un objet complexe. Les valeurs créées avec ref() sont accessibles via la propriété .value.

Points clés :
  • Idéal pour gérer des valeurs primitives réactives.
  • Les objets ou tableaux utilisés avec ref() ne sont pas automatiquement réactifs dans leurs propriétés imbriquées.
  • Compatible avec des opérations simples comme des incréments ou des modifications directes.

Syntaxe et utilisation

La fonction ref() est principalement utilisée pour des valeurs réactives simples.

// Création d'une valeur réactive avec ref()
import { ref } from 'vue';

// Déclaration d'une valeur réactive
const compteur = ref(0);

// Modification de la valeur
compteur.value++;
console.log(compteur.value); // Affiche 1
    

Exemple pratique

Voici un exemple où ref() est utilisé dans un composant pour gérer une valeur réactive avec des événements d'interaction.

// Exemple dans un composant Vue
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
        // Valeurs réactives
        const message = ref('Bonjour Vue.js!');
        const compteur = ref(0);

        // Méthode pour incrémenter
        const incrementer = () => {
            compteur.value++;
        };

        return { message, compteur, incrementer };
    },
    template: `
        <div>
            <p>{{ message }}</p>
            <p>Compteur : {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Utilisation avancée avec ref()

Lorsque ref() est appliqué à des objets ou des tableaux, seules les modifications au niveau racine sont suivies de manière réactive. Pour une réactivité complète, il est recommandé d'utiliser reactive() ou toRefs().

// Exemple avec un tableau réactif
import { ref } from 'vue';

// Déclaration d'un tableau réactif
const liste = ref([1, 2, 3]);

// Modification du tableau
liste.value.push(4);
console.log(liste.value); // Affiche [1, 2, 3, 4]
    

Bonnes pratiques

  • Utilisez ref() pour les valeurs primitives ou les tableaux simples.
  • Évitez d'utiliser ref() pour les objets complexes imbriqués. Préférez reactive() dans ces cas.
  • Gardez les noms de vos références descriptifs pour améliorer la lisibilité.
  • Minimisez l'utilisation de value directement dans les templates pour éviter les erreurs de logique.

Pratiques courantes

Créer un compteur : Un des usages les plus courants de ref() est de gérer un compteur ou une valeur qui évolue dynamiquement en fonction des événements.

// Exemple : Gestion d'un compteur
import { ref } from 'vue';

const compteur = ref(0);

// Incrémenter
compteur.value++;

// Décrémenter
compteur.value--;
    

Observabilité dans Vue Devtools : Les valeurs créées avec ref() apparaissent clairement dans Vue Devtools, ce qui facilite le débogage.

Fonction reactive()

Introduction

La fonction reactive() est une pierre angulaire de la Composition API dans Vue 3. Elle permet de créer des objets réactifs qui sont profondément observés par le système de réactivité de Vue. Contrairement à ref(), qui est destiné aux valeurs primitives ou simples, reactive() est spécialement conçu pour les objets et tableaux complexes.

Points clés :
  • Convient aux structures de données imbriquées comme les objets ou les tableaux.
  • Propose une réactivité profonde pour suivre les modifications dans les propriétés imbriquées.
  • Les modifications effectuées sur les objets réactifs sont automatiquement reflétées dans les templates Vue.

Syntaxe et utilisation

La fonction reactive() est idéale pour créer des objets réactifs complets.

// Création d'un objet réactif avec reactive()
import { reactive } from 'vue';

// Déclaration d'un objet réactif
const state = reactive({
    nom: 'Alice',
    age: 25,
    competences: ['JavaScript', 'Vue.js']
});

// Modification d'une propriété
state.age = 26;

// Ajout dans un tableau
state.competences.push('TypeScript');
    

Exemple pratique

Voici un exemple où reactive() est utilisé pour gérer un objet contenant des informations utilisateur, tout en réagissant aux modifications de ses propriétés dans un composant Vue.

// Exemple dans un composant Vue
import { defineComponent, reactive } from 'vue';

export default defineComponent({
    setup() {
        // Objet réactif
        const utilisateur = reactive({
            nom: 'Jean',
            age: 30,
            competences: ['HTML', 'CSS']
        });

        // Méthode pour ajouter une compétence
        const ajouterCompetence = (competence) => {
            utilisateur.competences.push(competence);
        };

        return { utilisateur, ajouterCompetence };
    },
    template: `
        <div>
            <p>Nom : {{ utilisateur.nom }}</p>
            <p>Âge : {{ utilisateur.age }}</p>
            <ul>
                <li v-for="competence in utilisateur.competences" :key="competence">
                    {{ competence }}
                </li>
            </ul>
            <button @click="ajouterCompetence('JavaScript')">Ajouter JavaScript</button>
        </div>
    `
});
    

Comparaison avec ref()

Bien que ref() puisse également être utilisé pour gérer des objets ou des tableaux, il ne fournit pas de réactivité profonde par défaut. Voici une comparaison des deux :

Critère reactive() ref()
Réactivité profonde Oui Non (besoin d'utiliser toRefs())
Simplicité pour les valeurs primitives Non Oui
Compatibilité avec les structures complexes Oui Oui (mais nécessite un accès via .value)

Bonnes pratiques

  • Utilisez reactive() pour des objets ou tableaux imbriqués nécessitant une réactivité complète.
  • Privilégiez ref() pour des valeurs primitives ou des structures simples.
  • Minimisez les mutations fréquentes sur des objets massifs pour éviter les performances dégradées.
  • Combinez reactive() avec toRefs() si vous devez déstructurer un objet tout en conservant la réactivité.

Pratiques courantes

Gestion d'un formulaire : Utilisez reactive() pour suivre les données d'un formulaire complexe avec plusieurs champs :

// Exemple : Suivi des données d'un formulaire
import { reactive } from 'vue';

const formulaire = reactive({
    nom: '',
    email: '',
    message: ''
});

// Modification d'un champ
formulaire.nom = 'Alice';
    

ref()

Introduction

La fonction ref() est un des piliers de la Composition API dans Vue 3. Elle permet de créer une valeur réactive qui peut être utilisée dans un composant ou partagée entre plusieurs composants.

Contrairement à reactive(), qui transforme des objets, ref() est principalement utilisé pour des valeurs primitives (comme des nombres, des chaînes de caractères) ou des objets simples. Il est particulièrement utile pour les propriétés qui doivent être modifiées dynamiquement et suivies de manière réactive.

Points clés :
  • Crée une valeur réactive encapsulée dans un objet avec une propriété .value.
  • Compatible avec des types primitifs ou des objets.
  • Idéal pour les cas où une valeur unique ou une référence doit être suivie.

Syntaxe et Utilisation

La syntaxe de ref() est simple et intuitive :

// Importation de ref
import { ref } from 'vue';

// Création d'une valeur réactive
const compteur = ref(0);

// Lecture et modification de la valeur
compteur.value++; 
console.log(compteur.value); // Affiche 1
    

Exemple pratique

Voici un exemple pratique où ref() est utilisé pour gérer une valeur réactive dans un composant Vue :

// Exemple de composant avec ref()
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
        // Création de données réactives
        const message = ref('Bonjour Vue.js!');
        const compteur = ref(0);

        // Méthode pour incrémenter le compteur
        const incrementer = () => {
            compteur.value++;
        };

        return { message, compteur, incrementer };
    },
    template: `
        <div>
            <p>{{ message }}</p>
            <p>Compteur : {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Comparaison : ref() vs reactive()

Bien que ref() et reactive() soient tous deux utilisés pour créer des données réactives, leurs cas d'utilisation diffèrent :

Critères ref() reactive()
Type de données Primitifs ou objets simples Objets complexes
Accès à la valeur .value Accès direct
Utilisation principale Valeurs isolées Objets imbriqués

Bonnes pratiques

  • Utilisez ref() pour des valeurs primitives comme les nombres, les chaînes de caractères ou les booléens.
  • Pour des objets ou des tableaux complexes, préférez reactive(), sauf si vous avez besoin d'une encapsulation fine.
  • Évitez de confondre ref() avec des valeurs non réactives ; utilisez-le uniquement lorsque la réactivité est nécessaire.

watch()

Introduction

La fonction watch() dans Vue 3 permet de réagir à des changements spécifiques dans les données réactives ou des refs. Contrairement à computed, qui calcule une valeur dérivée et mise en cache, watch() exécute une logique ou déclenche des effets secondaires lorsque les données changent.

Elle est particulièrement utile pour :

À retenir : Utilisez watch() lorsque vous avez besoin d'un effet secondaire basé sur un changement de données spécifique, et non pour des valeurs calculées directement dans le template.

Syntaxe et utilisation

La fonction watch() prend deux arguments principaux :

Elle accepte également un objet d'options pour définir des comportements comme l'observation en profondeur (deep) ou le déclenchement immédiat (immediate).

// Exemple de base avec watch()
import { ref, watch } from 'vue';

// Création d'une valeur réactive
const compteur = ref(0);

// Utilisation de watch()
watch(
    compteur, 
    (nouvelleValeur, ancienneValeur) => {
        console.log(`Compteur changé de ${ancienneValeur} à ${nouvelleValeur}`);
    }
);

// Mise à jour de la valeur
compteur.value++;
    

Exemple pratique

Voici un exemple où watch() est utilisé pour surveiller une recherche utilisateur et exécuter un appel API lorsque la valeur change :

// Exemple : Surveiller une recherche
import { ref, watch } from 'vue';

// Création de données réactives
const recherche = ref('');
const resultats = ref([]);

// Surveiller les changements de recherche
watch(
    recherche, 
    async (nouvelleRecherche) => {
        if (nouvelleRecherche.length > 3) {
            // Appel API
            const response = await fetch(`https://api.example.com/search?q=${nouvelleRecherche}`);
            resultats.value = await response.json();
        }
    },
    { immediate: true } // Lance dès la première exécution
);
    

Options avancées

La fonction watch() supporte plusieurs options qui permettent de personnaliser son comportement :

Option Description Valeurs possibles
deep Surveille profondément un objet ou tableau. true ou false
immediate Exécute immédiatement après la création. true ou false

Bonnes pratiques

  • Utilisez watch() pour les effets secondaires et les actions asynchrones.
  • Pour observer plusieurs dépendances, utilisez un tableau dans le premier argument : watch([dépendance1, dépendance2], callback).
  • Limitez l'usage de deep aux cas nécessaires pour éviter une surcharge de performance.
  • Combinez avec des composables pour réutiliser la logique d'observation dans plusieurs composants.

watchEffect()

Introduction

La fonction watchEffect() est une autre méthode de surveillance dans la Composition API de Vue 3. Contrairement à watch(), elle ne nécessite pas d'arguments explicites pour spécifier les dépendances. Les dépendances réactives utilisées dans le corps de la fonction sont automatiquement détectées, et l'effet est exécuté chaque fois qu'une dépendance change.

Elle est utile pour :

À retenir : Utilisez watchEffect() pour des besoins simples où les dépendances peuvent être détectées automatiquement, et préférez watch() pour une personnalisation avancée.

Syntaxe de base

La fonction watchEffect() prend une fonction en argument. Cette fonction est exécutée immédiatement lors de l'enregistrement et chaque fois qu'une dépendance change.

// Exemple de base avec watchEffect()
import { ref, watchEffect } from 'vue';

// Création de valeurs réactives
const compteur = ref(0);
const double = ref(0);

// Utilisation de watchEffect()
watchEffect(() => {
    double.value = compteur.value * 2;
    console.log(`Compteur: ${compteur.value}, Double: ${double.value}`);
});

// Mise à jour de la valeur
compteur.value++;
    

Exemple pratique

Voici un exemple où watchEffect() est utilisé pour surveiller un état réactif et mettre à jour dynamiquement le DOM :

// Exemple : Mise à jour automatique
import { ref, watchEffect } from 'vue';

// Création de données réactives
const message = ref('Bonjour Vue.js!');

// Mise à jour automatique avec watchEffect()
watchEffect(() => {
    document.querySelector('#output').textContent = message.value;
});

// Changer la valeur après 2 secondes
setTimeout(() => {
    message.value = 'Bonjour Composition API!';
}, 2000);
    

Comparaison avec watch()

La principale différence entre watch() et watchEffect() réside dans la gestion des dépendances :

Caractéristique watch() watchEffect()
Spécification des dépendances Manuelle Automatique
Complexité Personnalisable et avancée Simple et rapide
Effet initial Optionnel (immediate) Exécuté immédiatement

Bonnes pratiques

  • Utilisez watchEffect() pour des scénarios simples où les dépendances sont évidentes et non ambiguës.
  • Évitez d’utiliser watchEffect() pour des effets coûteux ou asynchrones ; préférez watch() dans ces cas.
  • Structurez les effets de manière à éviter des dépendances circulaires.
  • Libérez les ressources avec des callbacks de nettoyage si nécessaire :
// Exemple avec nettoyage
watchEffect((onCleanup) => {
    // Établir un intervalle
    const interval = setInterval(() => {
        console.log("Effet actif");
    }, 1000);

    // Nettoyer l'intervalle lors de la destruction
    onCleanup(() => {
        clearInterval(interval);
    });
});
    

Hooks du Cycle de Vie

Introduction

Les hooks de cycle de vie dans Vue 3 permettent de réagir à des événements spécifiques du cycle de vie d'un composant. Cela inclut des étapes comme l'initialisation, le rendu, les mises à jour et la destruction. En utilisant la Composition API, les hooks offrent une manière flexible et modulaire d'organiser la logique métier.

Avec l'Options API, des méthodes comme mounted et destroyed étaient utilisées. Dans la Composition API, ces méthodes sont remplacées par des fonctions spécifiques comme onMounted et onUnmounted.

Pourquoi sont-ils importants ?
  • Ils permettent de structurer proprement la logique en fonction des étapes du cycle de vie.
  • Ils facilitent l'intégration avec des APIs, les timers, ou d'autres systèmes asynchrones.
  • Ils améliorent la maintenabilité et la lisibilité du code dans des projets complexes.

Vue d'ensemble des Hooks

Voici une liste complète des hooks de cycle de vie disponibles dans Vue 3 avec leurs moments d'exécution :

Hook Description Moment d'exécution
onBeforeMount Exécuté avant que le DOM soit monté pour la première fois. Avant le rendu initial.
onMounted Exécuté une fois que le DOM est monté et accessible. Après le rendu initial.
onBeforeUpdate Exécuté avant qu'une mise à jour du DOM ne soit effectuée. Avant chaque mise à jour réactive.
onUpdated Exécuté après qu'une mise à jour du DOM ait été effectuée. Après chaque mise à jour réactive.
onBeforeUnmount Exécuté juste avant que le composant soit détruit. Avant la destruction du composant.
onUnmounted Exécuté après que le composant a été détruit. Après la destruction du composant.

Exemple pratique

Voici un exemple détaillé qui illustre comment utiliser différents hooks dans un composant Vue. Ce composant suit l'état réactif, effectue des actions au montage, met à jour une variable au besoin, et nettoie les ressources à la destruction.

// Exemple complet avec hooks de cycle de vie
import { defineComponent, ref, onMounted, onUpdated, onUnmounted } from 'vue';

export default defineComponent({
    setup() {
        // Déclare une valeur réactive
        const compteur = ref(0);

        // Hook exécuté après le montage
        onMounted(() => {
            console.log('Composant monté');
        });

        // Hook exécuté après chaque mise à jour
        onUpdated(() => {
            console.log('Composant mis à jour');
        });

        // Hook exécuté après la destruction
        onUnmounted(() => {
            console.log('Composant détruit');
        });

        // Méthode pour incrémenter
        const incrementer = () => {
            compteur.value++;
        };

        return {
            compteur,
            incrementer
        };
    },
    template: `
        <div>
            <p>Compteur : {{ compteur }}</p>
            <button @click="incrementer">Incrémenter</button>
        </div>
    `
});
    

Pratiques courantes

  • Utilisez onMounted pour effectuer des appels API initiaux ou configurer des abonnements.
  • Utilisez onUnmounted pour nettoyer les timers, les écouteurs d'événements ou les abonnements.
  • Combinez onUpdated avec des vérifications conditionnelles pour éviter des mises à jour inutiles.
  • Structurez les hooks de manière logique et minimisez leur contenu en délégant la logique complexe à des fonctions externes.

Bonnes pratiques

  • Évitez de surcharger les hooks comme onMounted : séparez les responsabilités en fonctions claires.
  • Privilégiez l'utilisation des composables pour réutiliser la logique de cycle de vie entre plusieurs composants.
  • Limitez l'utilisation de onUpdated si vous pouvez utiliser des watchers pour détecter des changements spécifiques.
  • Documentez les hooks dans votre code pour indiquer leur rôle et les raisons de leur utilisation.

Tendances actuelles

Les hooks de cycle de vie gagnent en popularité dans Vue 3 grâce à leur flexibilité dans la Composition API. Voici quelques tendances actuelles :

Utilisation Avancée et Composables

Introduction

La Composition API dans Vue 3 ne se limite pas aux fonctionnalités de base comme setup() ou reactive(). Elle ouvre la voie à des pratiques avancées et à la création de composables personnalisés. Ces composables permettent de réutiliser et d'organiser la logique dans des fonctions autonomes et modulaires, rendant le code plus propre, plus maintenable et plus testable.

Pourquoi les composables ?
  • Encapsulation de la logique métier pour la réutilisabilité.
  • Séparation claire des préoccupations dans des projets complexes.
  • Facilitation des tests unitaires et des maintenances futures.

Création d'un composable personnalisé

Un composable est une fonction JavaScript qui utilise la Composition API pour encapsuler une logique spécifique. Voici un exemple de composable permettant de gérer une valeur réactive et un timer.

// Composable personnalisé : useTimer
import { ref, onMounted, onUnmounted } from 'vue';

export function useTimer() {
    // Déclaration d'une valeur réactive
    const compteur = ref(0);
    let intervalId = null;

    // Fonction de démarrage
    const startTimer = () => {
        intervalId = setInterval(() => {
            compteur.value++;
        }, 1000);
    };

    // Fonction d'arrêt
    const stopTimer = () => {
        clearInterval(intervalId);
    };

    // Gestion des hooks de cycle de vie
    onMounted(startTimer);
    onUnmounted(stopTimer);

    // Retourne les propriétés et méthodes
    return {
        compteur,
        startTimer,
        stopTimer
    };
}
    

Utilisation dans un composant

Une fois créé, le composable peut être utilisé dans n'importe quel composant. Voici comment l'utiliser pour afficher un compteur.

// Composant utilisant le composable
import { defineComponent } from 'vue';
import { useTimer } from './composables/useTimer';

export default defineComponent({
    setup() {
        // Utilisation du composable
        const { compteur, startTimer, stopTimer } = useTimer();

        return { compteur, startTimer, stopTimer };
    },
    template: `
        <div>
            <p>Compteur : {{ compteur }}</p>
            <button @click="startTimer">Démarrer</button>
            <button @click="stopTimer">Arrêter</button>
        </div>
    `
});
    

Pratiques courantes

  • Créez des composables pour des fonctionnalités réutilisables comme la gestion des formulaires, les appels API ou la gestion des événements.
  • Documentez vos composables pour faciliter leur adoption par d'autres développeurs.
  • Organisez vos composables dans un dossier dédié (/src/composables) pour une meilleure lisibilité.
  • Combinez plusieurs composables pour des cas d'utilisation plus complexes.

Bonnes pratiques

  • Utilisez des noms descriptifs pour vos composables, comme useForm ou useFetch.
  • Évitez de surcharger un composable avec plusieurs responsabilités : appliquez le principe de responsabilité unique.
  • Testez vos composables indépendamment pour garantir leur fiabilité.
  • Réutilisez des APIs existantes comme reactive(), ref(), et watch() pour tirer parti de la réactivité native.

Tendances actuelles

Avec Vue 3, les composables personnalisés sont devenus un standard pour structurer les projets modernes. Voici quelques tendances émergentes :

Exemple de Projet

Introduction

Créer un projet Vue 3 avec la Composition API permet de mieux comprendre comment structurer et organiser un projet moderne. Dans cette section, nous allons développer une petite application de gestion de tâches pour illustrer l'utilisation des concepts clés de Vue 3, notamment les composables, la gestion du state avec Vuex, et le router.

Objectifs du projet :
  • Gérer une liste de tâches avec ajout, suppression et modification.
  • Utiliser Vuex pour centraliser la gestion des données.
  • Implémenter un système de navigation avec Vue Router.
  • Suivre les bonnes pratiques modernes pour structurer le projet.

Structure du projet

Voici la structure des dossiers et fichiers pour notre projet :

// Structure des fichiers
project/
|-- src/
|   |-- components/
|   |   |-- TaskList.vue
|   |   |-- TaskForm.vue
|   |-- composables/
|   |   |-- useTasks.js
|   |-- store/
|   |   |-- index.js
|   |-- views/
|   |   |-- Home.vue
|   |   |-- About.vue
|   |-- router/
|   |   |-- index.js
|   |-- App.vue
|   |-- main.js
    

Exemple de Code

Composable : useTasks.js

Ce composable encapsule la logique liée à la gestion des tâches.

// src/composables/useTasks.js
import { ref } from 'vue';

export function useTasks() {
    const tasks = ref([
        { id: 1, title: 'Apprendre Vue 3', done: false },
        { id: 2, title: 'Créer une application de tâches', done: true }
    ]);

    // Ajouter une tâche
    const addTask = (task) => {
        tasks.value.push({
            id: tasks.value.length + 1,
            ...task
        });
    };

    // Supprimer une tâche
    const deleteTask = (id) => {
        tasks.value = tasks.value.filter(task => task.id !== id);
    };

    return { tasks, addTask, deleteTask };
}
    

Composant : TaskList.vue

Le composant TaskList.vue affiche les tâches et propose des actions pour les gérer.

// src/components/TaskList.vue
import { defineComponent } from 'vue';
import { useTasks } from '@/composables/useTasks';

export default defineComponent({
    setup() {
        // Utilisation du composable
        const { tasks, deleteTask } = useTasks();

        return { tasks, deleteTask };
    },
    template: `
        <ul>
            <li v-for="task in tasks" :key="task.id">
                {{ task.title }}
                <button @click="deleteTask(task.id)">Supprimer</button>
            </li>
        </ul>
    `
});
    

Bonnes Pratiques

  • Utilisez des composables pour encapsuler des logiques spécifiques.
  • Structurez votre projet pour séparer les responsabilités (composants, store, router, etc.).
  • Adoptez un style cohérent pour le code et la nomenclature des fichiers.
  • Utilisez des bibliothèques de composants pour accélérer le développement (ex. : Vuetify, Element Plus).

Tendances Actuelles

Les tendances actuelles en développement Vue incluent :

Améliorations pour le Projet Vue.js

Introduction

Une fois le projet de base fonctionnel, il est utile d'explorer des fonctionnalités plus avancées pour rendre l'application plus riche, robuste et adaptée à des cas d'utilisation réels. Cette section présente des pistes d'amélioration et des exemples concrets pour enrichir votre projet Vue.js.

Ajout de la persistance des données

Les données actuelles sont volatiles et disparaissent lorsque la page est actualisée. Pour conserver les tâches, nous pouvons utiliser :

// Exemple d'utilisation de LocalStorage
import { ref, watch } from 'vue';

export default function useTasks() {
    const tasks = ref(JSON.parse(localStorage.getItem('tasks')) || []);

    // Surveiller les modifications et mettre à jour le stockage
    watch(tasks, (newTasks) => {
        localStorage.setItem('tasks', JSON.stringify(newTasks));
    }, { deep: true });

    // Ajout et suppression de tâches
    const addTask = (task) => tasks.value.push(task);
    const removeTask = (index) => tasks.value.splice(index, 1);

    return { tasks, addTask, removeTask };
}
    

Intégration avec une API REST

Utiliser fetch ou axios pour communiquer avec un serveur peut transformer votre projet en une véritable application web dynamique.

// Exemple avec Axios pour charger et envoyer des données
import axios from 'axios';
import { ref, onMounted } from 'vue';

export default function useTasks() {
    const tasks = ref([]);
    const error = ref('');

    // Charger les tâches depuis une API
    const loadTasks = async () => {
        try {
            const response = await axios.get('https://api.example.com/tasks');
            tasks.value = response.data;
        } catch (e) {
            error.value = 'Erreur lors du chargement des tâches.';
        }
    };

    // Ajouter une nouvelle tâche
    const addTask = async (task) => {
        try {
            const response = await axios.post('https://api.example.com/tasks', task);
            tasks.value.push(response.data);
        } catch (e) {
            error.value = 'Erreur lors de l\'ajout d\'une tâche.';
        }
    };

    onMounted(loadTasks);

    return { tasks, addTask, error };
}
    

Ajout de filtres

Vous pouvez ajouter des filtres pour organiser et afficher les tâches en fonction de leur état (terminées, en cours, etc.).

// Exemple de filtre pour les tâches terminées
import { computed } from 'vue';

export default function useFilteredTasks(tasks) {
    const completedTasks = computed(() => tasks.value.filter(task => task.completed));
    const pendingTasks = computed(() => tasks.value.filter(task => !task.completed));

    return { completedTasks, pendingTasks };
}
    

Amélioration du style

Donnez un aspect professionnel à votre application en utilisant des bibliothèques comme Tailwind CSS ou Vuetify.

// Exemple avec Tailwind CSS
<div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
    <h1 class="text-2xl font-bold mb-4">Tâches</h1>
    <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
        Ajouter une tâche
    </button>
</div>
    

Vue.js : Advanced Topics

Ce chapitre explore les sujets avancés de Vue.js, conçus pour optimiser les performances, la modularité et la robustesse de vos applications. Ces concepts vous permettent de gérer des cas d'utilisation complexes et de repousser les limites des possibilités offertes par Vue.js.

Ces sujets incluent :

  • Suspense : Pour gérer les états asynchrones avec élégance.
  • Teleport : Pour rendre des éléments dans un DOM différent de celui de leur composant parent.
  • Provide/Inject : Pour partager des données entre composants sans passer par des props.
  • Dynamic Imports : Pour charger des composants ou modules de façon dynamique.
  • Error Handling : Pour mieux gérer les erreurs dans vos applications.
Objectif : Vous équiper des outils nécessaires pour gérer des scénarios avancés tout en gardant vos applications performantes, maintenables et faciles à déboguer.

Vue.js : Suspense

Introduction

Suspense est une fonctionnalité puissante introduite dans Vue 3 pour gérer les composants asynchrones avec élégance. Elle permet de définir un état de "chargement" pendant que les données ou les ressources nécessaires à un composant sont en cours de traitement. Suspense améliore l'expérience utilisateur en affichant un contenu provisoire, comme un indicateur de chargement, jusqu'à ce que tout soit prêt.

Le concept de Suspense repose sur la promesse que les données ou les composants asynchrones se résoudront correctement. Cela simplifie la gestion d'états complexes et favorise une interface utilisateur fluide.

Points Clés

  • Suspense s'utilise comme un wrapper pour les composants asynchrones.
  • Il permet de définir un fallback (contenu de repli) qui s'affiche pendant le chargement.
  • Compatible avec les composants asynchrones et les données provenant de fonctions comme setup().

Fonctionnement de Suspense

Voici la structure de base pour utiliser Suspense :

<template>
    <Suspense>
        <template #default>
            <MyAsyncComponent />
        </template>
        <template #fallback>
            <div>Chargement en cours...</div>
        </template>
    </Suspense>
</template>
        

Exemple Simple

Voici un exemple pratique où un composant asynchrone est chargé avec Suspense.

// Composant principal
import { defineComponent } from 'vue';
import MyAsyncComponent from './MyAsyncComponent.vue';

export default defineComponent({
    components: {
        MyAsyncComponent
    }
});
        
<template>
    <Suspense>
        <template #default>
            <MyAsyncComponent />
        </template>
        <template #fallback>
            <div>Chargement en cours...</div>
        </template>
    </Suspense>
</template>
        

Exemples Pratiques

Chargement d'une liste d'articles : Utilisation de Suspense pour afficher un loader pendant le chargement de données.

// MyAsyncComponent.vue
import { defineComponent, ref, onMounted } from 'vue';

export default defineComponent({
    setup() {
        const articles = ref([]);
        const chargerArticles = async () => {
            const response = await fetch('https://api.example.com/articles');
            articles.value = await response.json();
        };

        onMounted(chargerArticles);

        return { articles };
    },
    template: `
        <ul>
            <li v-for="article in articles" :key="article.id">
                {{ article.title }}
            </li>
        </ul>
    `
});
        

Bonnes Pratiques

  • Fournir des messages de fallback clairs et informatifs pour une meilleure expérience utilisateur.
  • Évitez de trop imbriquer les composants Suspense, cela peut compliquer la lisibilité.
  • Utilisez Suspense uniquement pour des opérations réellement asynchrones.
  • Combinez Suspense avec des loaders animés pour un meilleur rendu visuel.

Tendances Actuelles

Avec l'essor des applications frontend modernes, Suspense est de plus en plus utilisé pour gérer efficacement les états de chargement. Il est souvent combiné avec des frameworks comme Nuxt.js ou des bibliothèques de gestion de données comme GraphQL pour offrir des expériences utilisateur fluides.

Vue.js : Teleport

Introduction

Le composant Teleport introduit dans Vue 3 permet de rendre un élément ou un composant dans un endroit différent de l'arborescence DOM normale de votre application. Cela est particulièrement utile pour des éléments comme les modales, les notifications, ou tout autre contenu qui doit apparaître en dehors de son parent logique tout en conservant son comportement et ses données.

Ce mécanisme est particulièrement utile lorsque vous avez besoin de placer un élément dans une section spécifique du DOM (comme une balise <body> ou un conteneur externe), sans modifier la structure de votre application.

Points Clés

  • Le composant <Teleport> permet de rendre son contenu dans un nœud DOM cible.
  • Il est très utile pour des éléments nécessitant une position absolue comme les modales ou les overlays.
  • Il conserve toutes les données et réactivités associées au composant téléporté.

Fonctionnement de Teleport

Voici un exemple de base pour comprendre comment <Teleport> fonctionne :

<template>
    <div>
        <h1>Bienvenue à Vue.js</h1>
        <Teleport to='#teleport-target'>
            <div>
                <h2>Contenu téléporté</h2>
            </div>
        </Teleport>
    </div>
</template>
        

Pour que cet exemple fonctionne, un conteneur cible doit exister dans votre DOM :

<div id='teleport-target'></div>
        

Exemples Pratiques

Voici une utilisation typique de <Teleport> pour gérer une modale :

<template>
    <div>
        <button @click='afficherModale = true'>
            Ouvrir la modale</button>
        <Teleport to='#modale-cible'>
            <div v-if='afficherModale' class='modale'>
                <h2>Modale Téléportée</h2>
                <button @click='afficherModale = false'>
                    Fermer</button>
            </div>
        </Teleport>
    </div>
</template>

import { ref } from 'vue';

export default {
    setup() {
        const afficherModale = ref(false);
        return { afficherModale };
    }
};
        

Bonnes Pratiques

  • Assurez-vous que le conteneur cible existe dans votre DOM avant de rendre le composant.
  • Utilisez des noms d'ID descriptifs pour vos cibles pour éviter les conflits.
  • Limitez l'utilisation de <Teleport> aux cas où cela est vraiment nécessaire.
  • Fournissez des styles CSS spécifiques pour le contenu téléporté afin qu'il s'intègre bien dans le reste de l'application.

Tendances Actuelles

L'utilisation de Teleport est en croissance, en particulier dans les applications où des composants dynamiques comme les modales ou les notifications sont omniprésents. Avec les applications web modernes nécessitant des interactions riches, Teleport devient un outil indispensable pour gérer les éléments hors contexte sans sacrifier la réactivité ou l'organisation du code.

Vue.js : Provide/Inject

Introduction

Le système Provide/Inject de Vue permet de partager des données entre un composant parent et ses descendants, sans avoir à les passer explicitement par les props ou les événements. Cette fonctionnalité est particulièrement utile dans les projets complexes où les données doivent être accessibles par plusieurs composants profondément imbriqués.

Avec provide, un composant parent peut mettre des données ou des méthodes à disposition de ses descendants. Ces derniers peuvent les consommer à l'aide de inject. Cela simplifie la gestion des dépendances dans l'arbre des composants.

Points Clés

  • Le provide est défini dans le parent pour partager des données ou des méthodes.
  • Le inject est utilisé dans les descendants pour consommer ces données.
  • Les données partagées restent réactives si elles sont définies avec ref ou reactive.

Fonctionnement de Provide/Inject

// Exemple avec provide/inject
// Parent.vue
import { defineComponent, provide, ref } from 'vue';

export default defineComponent({
    setup() {
        // Donnée partagée
        const theme = ref('dark');

        // Fournir la donnée aux descendants
        provide('theme', theme);

        return { theme };
    },
    template: `
        <div>
            <p>Thème actuel : {{ theme }}</p>
            <Child />
        </div>
    `
});
        
// Child.vue
import { defineComponent, inject } from 'vue';

export default defineComponent({
    setup() {
        // Consommer la donnée injectée
        const theme = inject('theme', 'light'); // Valeur par défaut : 'light'

        return { theme };
    },
    template: `
        <div>
            <p>Thème injecté : {{ theme }}</p>
        </div>
    `
});
        

Exemple Pratique

Imaginez une application où un paramètre de configuration (comme un thème ou une langue) doit être utilisé dans plusieurs composants. Le système provide/inject est idéal pour ce cas d'utilisation.

// Exemple : Partage de configuration
// ConfigProvider.vue
import { defineComponent, provide, reactive } from 'vue';

export default defineComponent({
    setup() {
        const config = reactive({
            theme: 'dark',
            language: 'fr'
        });

        provide('config', config);

        return { config };
    },
    template: `
        <div>
            <slot />
        </div>
    `
});
        
// ConfigConsumer.vue
import { defineComponent, inject } from 'vue';

export default defineComponent({
    setup() {
        const config = inject('config');

        return { config };
    },
    template: `
        <div>
            <p>Thème : {{ config.theme }}</p>
            <p>Langue : {{ config.language }}</p>
        </div>
    `
});
        

Bonnes Pratiques

  • Utilisez provide/inject pour des cas spécifiques comme les thèmes ou les configurations globales.
  • Privilégiez les props et événements pour les données directement utilisées entre un parent et un enfant.
  • Fournissez des valeurs par défaut dans inject pour éviter les erreurs en cas d'absence de provide.
  • Regroupez les données injectées dans des objets structurés pour faciliter leur utilisation.

Tendances Actuelles

L'utilisation de provide/inject a gagné en popularité avec Vue 3, notamment dans le développement de bibliothèques de composants comme Vue Router ou Vuex. Cette approche offre une grande flexibilité pour gérer des dépendances complexes sans compromettre la maintenabilité du code.

Vue.js : Dynamic Imports

Introduction

Les Dynamic Imports permettent de charger des modules JavaScript uniquement lorsque cela est nécessaire, au lieu de les inclure directement dans le bundle principal. Cela permet d'optimiser les performances des applications, notamment en réduisant le temps de chargement initial. En Vue.js, cette technique est couramment utilisée pour charger des composants dynamiquement ou en fonction des besoins spécifiques d'un utilisateur.

Points Clés

  • Les imports dynamiques sont une fonctionnalité native de JavaScript avec import().
  • Ils fonctionnent très bien avec des outils de bundling comme Webpack ou Vite.
  • Ils permettent le code splitting, c’est-à-dire la séparation du code en plusieurs fichiers indépendants.
  • Idéal pour les composants rarement utilisés ou conditionnels.

Fonctionnement de Dynamic Imports

Exemple de Base

Voici comment utiliser un import dynamique pour charger un composant en fonction d'une condition.

// Import dynamique d'un composant
const MonComposant = () => import('./components/MonComposant.vue');

// Utilisation dans Vue
export default {
    components: {
        MonComposant
    },
    template: `
        <div>
            <MonComposant />
        </div>
    `
};
        

Exemple Pratique avec Vue Router

Les imports dynamiques sont particulièrement utiles avec Vue Router pour charger les composants des routes uniquement lorsqu'ils sont nécessaires.

// Définition de routes avec imports dynamiques
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
    {
        path: '/home',
        component: () => import('./views/HomeView.vue')
    },
    {
        path: '/about',
        component: () => import('./views/AboutView.vue')
    }
];

const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router;
        

Bonnes Pratiques

  • Utilisez des imports dynamiques pour les composants rarement utilisés (ex. : pages d’erreur, modales spécifiques).
  • Organisez votre projet en modules ou features pour une meilleure maintenabilité.
  • Préchargez (prefetch) les fichiers si vous savez qu’ils seront nécessaires prochainement pour améliorer l’expérience utilisateur.
  • Testez régulièrement les bundles générés pour vous assurer qu’ils restent optimisés.

Tendances Actuelles

Avec l'essor des applications performantes, les imports dynamiques deviennent indispensables. Les outils modernes comme Vite ou Webpack 5 offrent des optimisations automatiques pour le code splitting. En outre, cette technique est de plus en plus utilisée pour les Progressive Web Apps (PWA) et les Single Page Applications (SPA) afin de minimiser le temps de chargement initial.

Exemple Complet

Voici un exemple combiné montrant comment organiser un projet avec des imports dynamiques pour les routes et les composants.

// Configuration Vue Router avec imports dynamiques
import { createRouter, createWebHistory } from 'vue-router';

const HomeView = () => import('./views/HomeView.vue');
const AboutView = () => import('./views/AboutView.vue');
const NotFound = () => import('./views/NotFound.vue');

const routes = [
    { path: '/', component: HomeView },
    { path: '/about', component: AboutView },
    { path: '/:catchAll(.*)', component: NotFound }
];

const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router;
        

Vue.js : Error Handling

Introduction

La gestion des erreurs est une étape cruciale pour garantir la robustesse et la fiabilité des applications. Vue.js offre plusieurs outils pour intercepter, signaler et gérer les erreurs, que ce soit au niveau global ou local. Avec Vue 3, le système est encore amélioré grâce à des fonctionnalités comme app.config.errorHandler et les composants ErrorBoundary.

Points Clés

  • Capture des erreurs globales via app.config.errorHandler.
  • Gestion locale des erreurs avec des blocs try/catch.
  • Possibilité de capturer les erreurs dans un sous-arbre avec un composant ErrorBoundary.

Gestion Globale des Erreurs

L'option app.config.errorHandler de Vue permet de centraliser la gestion des erreurs pour toute l'application. Elle intercepte les erreurs non capturées, qu'elles proviennent des composants, des hooks ou des erreurs asynchrones.

// Gestion globale des erreurs
import { createApp } from 'vue';

const app = createApp({});

app.config.errorHandler = (err, instance, info) => {
    console.error('Erreur capturée :', err);
    console.error('Contexte :', info);
};

app.mount('#app');
        

Gestion Locale des Erreurs

Les erreurs spécifiques à un composant ou une logique métier peuvent être gérées localement en utilisant des blocs try/catch.

// Gestion locale avec try/catch
export default {
    methods: {
        async chargerDonnees() {
            try {
                const response = await fetch('/api/donnees');
                const donnees = await response.json();
                return donnees;
            } catch (err) {
                console.error('Erreur lors du chargement :', err);
            }
        }
    }
};
        

Exemple Pratique avec un Composant ErrorBoundary

Un composant ErrorBoundary est utilisé pour capturer les erreurs dans une section spécifique de l'arbre des composants. Il permet de gérer des erreurs sans affecter le reste de l'application.

// ErrorBoundary.vue
export default {
    data() {
        return { erreur: null };
    },
    errorCaptured(err, instance, info) {
        this.erreur = err;
        console.error('Erreur capturée dans ErrorBoundary :', err);
        return false; // Empêche la propagation
    },
    template: `
        <div>
            <slot v-if="!erreur" />
            <p v-else>Une erreur s'est produite : {{ erreur.message }}</p>
        </div>
    `
};
        

Bonnes Pratiques

  • Utilisez app.config.errorHandler pour capturer et centraliser les erreurs non gérées.
  • Pour les composants critiques, implémentez un composant ErrorBoundary.
  • Ajoutez des logs détaillés dans vos gestionnaires d'erreurs pour faciliter le débogage.
  • Ne mélangez pas la logique métier et la gestion des erreurs : isolez cette dernière pour une meilleure lisibilité.

Tendances Actuelles

L'intégration d'outils tiers comme Sentry ou Rollbar pour la gestion et le suivi des erreurs est de plus en plus courante. Ces outils offrent des tableaux de bord et des alertes en temps réel pour identifier rapidement les problèmes en production.

Vue.js : Transitions et Animations

Introduction

Les transitions et animations sont des éléments essentiels pour améliorer l'expérience utilisateur en rendant les interfaces plus dynamiques et intuitives. Vue.js offre un système puissant et flexible pour gérer les transitions des éléments DOM lors de leur apparition, disparition ou modification.

Grâce aux composants intégrés comme <transition> et <transition-group>, vous pouvez facilement appliquer des classes CSS ou utiliser JavaScript pour créer des animations personnalisées. De plus, Vue.js propose des hooks pour contrôler les étapes du cycle d'animation, permettant une personnalisation avancée.

Points Clés

  • Le composant <transition> est utilisé pour animer un élément unique lors de son ajout ou de sa suppression du DOM.
  • Le composant <transition-group> permet d'animer une liste d'éléments.
  • Vue.js prend en charge les animations basées sur CSS, JavaScript et des bibliothèques tierces comme Anime.js ou GSAP.
  • Les hooks d'animation offrent un contrôle précis sur le cycle de vie des transitions.

Pourquoi utiliser les transitions et animations ?

  • Pour guider l'utilisateur à travers l'interface avec des effets visuels subtils.
  • Pour rendre les changements d'état ou de contenu plus naturels et fluides.
  • Pour attirer l'attention sur des éléments interactifs, comme des boutons ou des notifications.

Vue.js : Transition

Introduction

Dans Vue.js, le composant <transition> est utilisé pour appliquer des animations lors de l'entrée ou de la sortie d'un élément du DOM. Il simplifie l'ajout de classes CSS ou l'exécution d'animations JavaScript pour des transitions fluides et professionnelles.

Grâce à <transition>, vous pouvez animer :

  • L'apparition et la disparition des éléments conditionnels (v-if, v-show).
  • Les modifications dynamiques des éléments dans le DOM.

Syntaxe de Base

Voici un exemple simple montrant comment utiliser le composant <transition> avec des classes CSS pour animer l'ajout ou la suppression d'un élément :

// Exemple Vue.js avec transition CSS
<template>
    <div>
        <button @click="visible = !visible">Toggle</button>
        <transition name="fade">
            <p v-if="visible">Bonjour, Vue.js !</p>
        </transition>
    </div>
</template>

<style>
.fade-enter-active, .fade-leave-active {
    transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
    opacity: 0;
}
</style>
        

Classes CSS Utilisées

Classe Description
fade-enter Appliquée au début de l'animation d'entrée.
fade-enter-active Active pendant toute la durée de l'animation d'entrée.
fade-leave Appliquée au début de l'animation de sortie.
fade-leave-active Active pendant toute la durée de l'animation de sortie.

Exemple Avancé : Transitions avec JavaScript

Vous pouvez combiner des transitions JavaScript pour un contrôle plus précis sur les animations :

// Transition avec hooks JavaScript
<template>
    <div>
        <button @click="visible = !visible">Toggle</button>
        <transition @before-enter="beforeEnter" @enter="enter" @leave="leave">
            <div v-if="visible">Contenu avec animation JavaScript</div>
        </transition>
    </div>
</template>

<script>
export default {
    data() {
        return {
            visible: false
        };
    },
    methods: {
        beforeEnter(el) {
            el.style.opacity = 0;
        },
        enter(el, done) {
            setTimeout(() => {
                el.style.opacity = 1;
                done();
            }, 500);
        },
        leave(el, done) {
            el.style.opacity = 0;
            setTimeout(done, 500);
        }
    }
};
</script>
        

Bonnes Pratiques

  • Utilisez des classes descriptives pour identifier clairement les transitions (par ex. fade, slide).
  • Testez vos animations pour garantir des performances fluides, même sur des appareils moins puissants.
  • Privilégiez CSS pour les animations simples et JavaScript pour les transitions complexes ou dépendantes de calculs dynamiques.

Tendances Actuelles

Les transitions et animations sont de plus en plus utilisées pour améliorer l'expérience utilisateur. Les tendances actuelles incluent :

  • L'utilisation de bibliothèques comme GSAP pour des animations avancées.
  • La mise en œuvre d'effets d'apparition en défilement avec des outils comme AOS (Animate On Scroll).
  • La conception d'animations micro-interactives pour des retours visuels rapides et fluides.

Vue.js : Transition-Group

Introduction

Le composant <transition-group> permet d'ajouter des animations aux listes d'éléments dynamiques dans Vue.js. Contrairement au composant <transition>, il est conçu pour gérer plusieurs éléments avec des entrées, des sorties et des réordonnancements animés.

Les animations avec <transition-group> fonctionnent en appliquant des classes CSS ou des hooks JavaScript à chaque élément de la liste lorsqu'il entre, quitte ou change de position.

Points Clés

  • Utilisez v-for pour générer dynamiquement les éléments à l'intérieur de <transition-group>.
  • Ajoutez l'attribut tag pour spécifier le conteneur HTML du groupe (par défaut <span>).
  • Chaque élément doit avoir une clé unique (key) pour permettre un suivi précis des modifications.

Exemple de Base

Voici un exemple simple utilisant <transition-group> pour animer l'ajout et la suppression d'éléments dans une liste :

// Composant avec transition-group
<template>
    <div>
        <button @click="ajouterItem">Ajouter un élément</button>
        <transition-group name="list" tag="ul">
            <li v-for="(item, index) in items" :key="index">
                {{ item }}
            </li>
        </transition-group>
    </div>
</template>

<script>
export default {
    data() {
        return {
            items: ['Item 1', 'Item 2', 'Item 3']
        };
    },
    methods: {
        ajouterItem() {
            this.items.push('Nouvel élément');
        }
    }
};
</script>

<style>
.list-enter-active, .list-leave-active {
    transition: all 0.5s;
}
.list-enter, .list-leave-to {
    opacity: 0;
    transform: translateY(20px);
}
</style>
        

Exemple Avancé : Réordonnancement Animé

Le composant <transition-group> permet également de gérer les réordonnancements d'éléments. Voici un exemple où des éléments sont déplacés dans la liste :

// Exemple avec réordonnancement
<template>
    <div>
        <button @click="mélanger">Mélanger</button>
        <transition-group name="shuffle" tag="ul">
            <li v-for="(item, index) in items" :key="item">
                {{ item }}
            </li>
        </transition-group>
    </div>
</template>

<script>
export default {
    data() {
        return {
            items: ['A', 'B', 'C', 'D']
        };
    },
    methods: {
        mélanger() {
            this.items = this.items.sort(() => Math.random() - 0.5);
        }
    }
};
</script>

<style>
.shuffle-enter-active, .shuffle-leave-active {
    transition: all 0.5s;
}
.shuffle-enter, .shuffle-leave-to {
    opacity: 0;
    transform: translateY(20px);
}
</style>
        

Bonnes Pratiques

  • Utilisez des clés (key) uniques pour chaque élément afin de garantir des animations précises.
  • Privilégiez l'utilisation des animations CSS pour des transitions simples, en raison de leur performance.
  • Testez vos transitions sur des appareils moins puissants pour garantir une fluidité optimale.
  • Utilisez des animations JavaScript pour des comportements plus complexes.

Tendances Actuelles

L'animation de listes dynamiques est devenue essentielle pour améliorer l'expérience utilisateur. Les tendances actuelles incluent :

  • L'utilisation de bibliothèques comme GSAP pour des animations plus complexes.
  • L'intégration avec des outils de design interactif pour des transitions innovantes.
  • L'accent sur l'accessibilité, en veillant à ce que les animations n'entravent pas les utilisateurs souffrant de troubles visuels ou cognitifs.

Vue.js : Animation Hooks

Introduction

Les hooks d'animation permettent d'exécuter du code JavaScript pendant différentes étapes d'une transition ou animation, offrant ainsi un contrôle précis sur le comportement des animations. Ces hooks sont utiles pour déclencher des actions spécifiques en fonction du cycle de vie de l'animation, comme démarrer une requête ou appliquer des transformations complexes.

Avec Vue.js, les hooks d'animation sont disponibles à la fois dans les composants <transition> et <transition-group>. Ils offrent une grande flexibilité pour personnaliser les comportements lors des entrées, sorties et transitions d'éléments.

Points Clés

  • Les hooks permettent d'intégrer des animations JavaScript complexes.
  • Ils fournissent un contrôle précis sur chaque phase de l'animation.
  • Idéal pour synchroniser des animations avec des événements externes ou des états dynamiques.

Les Hooks Disponibles

Hook Description Arguments
before-enter Appelé avant qu'un élément commence à entrer. Élément cible
enter Appelé lorsque l'élément commence à entrer. Élément cible, fonction done
after-enter Appelé une fois que l'entrée est terminée. Élément cible
enter-cancelled Appelé si l'entrée est annulée. Élément cible
before-leave Appelé avant qu'un élément commence à quitter. Élément cible
leave Appelé lorsque l'élément commence à quitter. Élément cible, fonction done
after-leave Appelé une fois que la sortie est terminée. Élément cible
leave-cancelled Appelé si la sortie est annulée. Élément cible

Exemple Pratique avec Hooks

Dans cet exemple, les hooks sont utilisés pour exécuter des actions personnalisées à chaque étape de l'animation d'un élément.

// Exemple avec hooks d'animation
<template>
    <div>
        <button @click="toggle">Afficher/Masquer</button>
        <transition
            @before-enter="avantEntrée"
            @enter="entrée"
            @after-enter="aprèsEntrée"
            @before-leave="avantSortie"
            @leave="sortie"
            @after-leave="aprèsSortie">
            <p v-if="visible">Contenu animé</p>
        </transition>
    </div>
</template>

<script>
export default {
    data() {
        return {
            visible: false
        };
    },
    methods: {
        toggle() {
            this.visible = !this.visible;
        },
        avantEntrée(el) {
            console.log('Avant Entrée', el);
        },
        entrée(el, done) {
            console.log('Entrée', el);
            setTimeout(done, 1000);
        },
        aprèsEntrée(el) {
            console.log('Après Entrée', el);
        },
        avantSortie(el) {
            console.log('Avant Sortie', el);
        },
        sortie(el, done) {
            console.log('Sortie', el);
            setTimeout(done, 1000);
        },
        aprèsSortie(el) {
            console.log('Après Sortie', el);
        }
    }
};
</script>

<style>
.p {
    transition: opacity 1s;
    opacity: 1;
}
.p-leave-active {
    opacity: 0;
}
</style>
        

Bonnes Pratiques

  • Utilisez les hooks d'animation pour synchroniser des tâches asynchrones ou des événements externes avec vos animations.
  • Gérez les animations longues avec une fonction done pour éviter les conflits de timing.
  • Testez les performances des animations JavaScript pour garantir leur fluidité sur tous les appareils.
  • Préférez les animations CSS pour des transitions simples et performantes.

Tendances Actuelles

Les hooks d'animation sont largement utilisés dans les applications modernes pour :

  • Synchroniser des animations avec des API ou des sockets Web.
  • Créer des expériences utilisateur immersives dans les applications interactives.
  • Améliorer l'accessibilité en combinant animations et annonces ARIA.

Sommaire : Server-Side Rendering

Server-Side Rendering (SSR)

Introduction

Le Server-Side Rendering (SSR) est une technique qui permet de générer le HTML d'une application côté serveur, puis de l'envoyer au client pour affichage. Contrairement au rendu côté client (Client-Side Rendering), où le contenu est généré directement dans le navigateur, le SSR offre des avantages en termes de performance, d'optimisation pour les moteurs de recherche (SEO) et d'expérience utilisateur.

En Vue.js, le SSR est pris en charge via des outils comme Vue Server Renderer ou des frameworks avancés tels que Nuxt.js, qui simplifient la configuration et offrent des fonctionnalités supplémentaires.

Points Clés du SSR

  • Rapidité de rendu : Le contenu est visible plus rapidement, car il est pré-rendu côté serveur.
  • SEO amélioré : Les moteurs de recherche peuvent facilement indexer le contenu statique généré.
  • Interactivité : Une fois chargé dans le navigateur, le contenu statique devient interactif grâce à la réhydratation.
  • Coût serveur : Générer du HTML côté serveur peut augmenter la charge du serveur pour des applications très dynamiques.
Pourquoi utiliser SSR ?
  • Améliorer le temps de chargement initial.
  • Optimiser les performances SEO.
  • Offrir une meilleure expérience utilisateur, notamment sur les connexions lentes.

SSR Overview

Introduction au Server-Side Rendering

Le Server-Side Rendering (SSR) consiste à générer du HTML complet côté serveur, prêt à être envoyé au navigateur client. Cette technique est particulièrement efficace pour améliorer la rapidité d'affichage des pages et l'optimisation pour les moteurs de recherche (SEO).

Dans Vue.js, SSR est rendu possible grâce à des outils intégrés comme vue-server-renderer. En utilisant SSR, le serveur génère une version HTML de votre application qui est immédiatement affichée dans le navigateur. Une fois chargée, Vue "hydrate" le HTML généré, activant les fonctionnalités dynamiques du framework.

Fonctionnement du SSR

  • Rendu côté serveur : Le serveur génère un HTML statique basé sur les données et le code de l'application.
  • Réhydratation : Une fois le HTML livré au client, Vue.js active l'application en liant le DOM existant au comportement interactif de Vue.

Comparaison : SSR vs CSR

Aspect SSR (Server-Side Rendering) CSR (Client-Side Rendering)
Temps de chargement initial Rapide (HTML généré côté serveur) Plus lent (JS doit être téléchargé et exécuté)
SEO Très bon (HTML complet disponible pour les crawlers) Mauvais (contenu généré via JS)
Charge serveur Plus élevée (rendu côté serveur) Moins élevée
Complexité Configuration avancée requise Simplifiée

Exemple basique de SSR avec Vue

Voici un exemple de configuration SSR avec Vue.js en utilisant le package vue-server-renderer.

// Installez le package vue-server-renderer
npm install vue vue-server-renderer
        
// server.js : Script de rendu côté serveur
const Vue = require('vue');
const renderer = require('vue-server-renderer').createRenderer();

// Créez une instance Vue
const app = new Vue({
    data: {
        message: 'Bonjour SSR!'
    },
    template: `<div>{{ message }}</div>`
});

// Génération HTML côté serveur
renderer.renderToString(app, (err, html) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(html); // Affiche le HTML complet
});
        

Bonnes pratiques

  • Utilisez SSR pour les applications nécessitant un bon SEO, comme les blogs ou les e-commerces.
  • Combinez SSR avec la réhydratation pour maintenir l'interactivité de l'application côté client.
  • Optimisez les performances serveur en mettant en cache le HTML généré pour des pages peu dynamiques.
  • Choisissez des frameworks comme Nuxt.js pour simplifier la mise en œuvre du SSR dans Vue.

Tendances actuelles

Le SSR est de plus en plus utilisé pour offrir des expériences utilisateur rapides tout en conservant un bon référencement. Avec la montée en popularité des Progressive Web Apps (PWA), les solutions SSR comme Nuxt.js et Next.js jouent un rôle crucial dans la performance des applications web modernes.

Nuxt.js

Introduction

Nuxt.js est un framework basé sur Vue.js qui simplifie le développement d'applications web modernes grâce à une structure prédéfinie et des fonctionnalités intégrées. Il est conçu pour prendre en charge le Server-Side Rendering (SSR), le Static Site Generation (SSG), et les applications monopages (SPA).

En utilisant Nuxt.js, les développeurs peuvent créer des applications performantes, optimisées pour le SEO et offrant une expérience utilisateur fluide. Avec sa configuration simplifiée et ses conventions, Nuxt.js permet de gagner du temps tout en maintenant une structure de projet claire.

Points Clés

  • Prise en charge native de SSR et SSG pour des performances optimales et un meilleur SEO.
  • Structure modulaire basée sur des fichiers, ce qui facilite l'organisation du code.
  • Outils intégrés comme Nuxt CLI, un système de plugins, et la gestion automatique des routes.

Installation et Configuration

Pour commencer avec Nuxt.js, suivez ces étapes :

// Installez Nuxt.js avec npm ou yarn
npm create nuxt-app my-nuxt-app
        

Cette commande vous guidera à travers une série de questions pour configurer votre projet Nuxt.js :

  • Choisissez le gestionnaire de paquets (npm, yarn).
  • Sélectionnez le mode de rendu (SSR, SSG ou SPA).
  • Ajoutez des modules supplémentaires (Axios, PWA, etc.).

Structure d'un projet Nuxt.js

Un projet Nuxt.js typique suit cette structure :

Dossier/Fichier Description
pages/ Contient les fichiers de pages. Chaque fichier représente une route.
components/ Contient les composants réutilisables.
layouts/ Définit les mises en page globales pour les pages.
store/ Gestionnaire de state (Vuex) pour l'état global.
nuxt.config.js Fichier de configuration principal pour Nuxt.js.

Exemple de projet simple

Voici un exemple d'application Nuxt.js qui utilise SSR pour afficher une liste d'articles depuis une API.

// pages/index.vue
<template>
    <div>
        <h1>Liste des Articles</h1>
        <ul>
            <li v-for="article in articles" :key="article.id">
                {{ article.title }}
            </li>
        </ul>
    </div>
</template>

<script>
export default {
    async asyncData({ $axios }) {
        const articles = await $axios.$get('https://jsonplaceholder.typicode.com/posts');
        return { articles };
    }
};
</script>
        

Bonnes Pratiques

  • Utilisez asyncData pour précharger les données avant le rendu côté serveur.
  • Séparez les composants en unités réutilisables pour améliorer la maintenabilité.
  • Configurez les métadonnées pour chaque page avec head() pour optimiser le SEO.
  • Exploitez les modules Nuxt comme @nuxt/image ou @nuxt/axios pour gagner en productivité.

Tendances Actuelles

Avec l'évolution des frameworks, Nuxt.js reste l'une des solutions les plus populaires pour créer des applications Vue.js robustes et optimisées. L'introduction de Nuxt 3, avec des fonctionnalités comme l'intégration native de Vue 3, Vite, et un support amélioré de TypeScript, renforce encore son adoption dans les projets modernes.

Vue.js : Testing

Introduction

Les tests sont une partie essentielle du cycle de vie du développement logiciel. En Vue.js, les tests permettent de garantir la stabilité, la maintenabilité et la qualité du code. Que ce soit pour tester des composants individuels ou des scénarios utilisateur complets, Vue.js offre des outils adaptés pour répondre à ces besoins.

Cette section est divisée en trois parties principales :

  • Unit Testing : Tester des composants ou des fonctions isolées.
  • End-to-End (E2E) Testing : Tester le comportement global de l'application, comme un utilisateur réel.
  • Vue Test Utils : Une bibliothèque spécifique à Vue pour simplifier les tests des composants Vue.js.
Pourquoi les tests sont importants :
  • Prévenir les régressions lors des mises à jour.
  • Améliorer la confiance dans le code et les déploiements.
  • Faciliter la collaboration dans des équipes de développement.
  • Documenter le comportement attendu du code.

Vue.js : Unit Testing

Qu'est-ce que le Unit Testing ?

Les tests unitaires se concentrent sur le test de petites unités de code de manière isolée, comme des fonctions ou des composants individuels. L'objectif est de vérifier que chaque unité fonctionne comme prévu.

En Vue.js, cela signifie généralement tester un composant Vue ou une méthode JavaScript en dehors de son environnement complet.

Configuration et outils recommandés

  • Jest : Un framework de test populaire et performant.
  • Vue Test Utils : Une bibliothèque officielle pour tester les composants Vue.
  • Mocha : Une autre alternative pour les tests unitaires.

Installer Jest

// Installation de Jest et Vue Test Utils
npm install --save-dev jest @vue/test-utils vue-jest
        

Exemple de test unitaire simple

Voici un exemple simple de test d'un composant Vue qui affiche un message et permet de l'incrémenter.

// Counter.vue
<template>
    <div>
        <p>{{ count }}</p>
        <button @click='increment'>Incrémenter</button>
    </div>
</template>

export default {
    data() {
        return {
            count: 0
        };
    },
    methods: {
        increment() {
            this.count++;
        }
    }
};
        

Test avec Jest

// Counter.spec.js
import { mount } from '@vue/test-utils';
import Counter from './Counter.vue';

// Décrire le groupe de tests
describe('Counter.vue', () => {
    // Test initial
    test('affiche le compteur initial', () => {
        const wrapper = mount(Counter);
        expect(wrapper.text()).toContain('0');
    });

    // Test du bouton
    test('incrémente le compteur', async () => {
        const wrapper = mount(Counter);
        const button = wrapper.find('button');
        await button.trigger('click');
        expect(wrapper.text()).toContain('1');
    });
});
        

Bonnes pratiques

  • Testez uniquement une unité de code à la fois.
  • Utilisez des descriptions claires et spécifiques pour vos tests.
  • Évitez les dépendances externes dans les tests unitaires.
  • Concentrez-vous sur les résultats attendus et le comportement du composant.

Tendances actuelles

Avec Vue 3, les tests unitaires gagnent en popularité grâce à Vue Test Utils et l'intégration transparente avec Jest. L'accent est mis sur les tests rapides, isolés et maintenables pour garantir la stabilité des composants.

Vue.js : End-to-End Testing (E2E Testing)

Qu'est-ce que le E2E Testing ?

Les tests End-to-End (E2E) vérifient l'application dans son intégralité, de bout en bout, en simulant le parcours utilisateur. Contrairement aux tests unitaires ou d'intégration, ils testent l'ensemble de la pile technologique (frontend, backend, base de données) et s'assurent que tout fonctionne comme prévu dans un environnement réel.

Objectifs des tests E2E

  • Vérifier que les fonctionnalités critiques fonctionnent pour l'utilisateur final.
  • Simuler des interactions utilisateur comme les clics, les formulaires, et la navigation.
  • Identifier les problèmes d'intégration entre les différents systèmes.

Outils pour E2E Testing

  • Cypress : Un outil populaire pour tester les applications web avec une syntaxe facile à utiliser.
  • Puppeteer : Une bibliothèque Node.js pour automatiser les tests dans un navigateur Chrome.
  • Playwright : Une alternative robuste à Puppeteer, prenant en charge plusieurs navigateurs.

Installation de Cypress

// Installation de Cypress
npm install cypress --save-dev

// Lancer Cypress
npx cypress open
        

Exemple de test E2E

Voici un exemple simple pour tester une application Vue.js avec Cypress. Le test vérifie que l'utilisateur peut naviguer sur la page d'accueil et soumettre un formulaire.

// cypress/integration/home.spec.js
describe('Test de la page d'accueil', () => {
    it('Affiche le titre de la page', () => {
        cy.visit('/');
        cy.contains('Bienvenue sur Vue.js!');
    });

    it('Soumet un formulaire', () => {
        cy.visit('/form');
        cy.get("#name").type('Jean Dupont');
        cy.get("#submit").click();
        cy.contains('Formulaire soumis!');
    });
});
        

Bonnes pratiques

  • Concentrez-vous sur les parcours critiques de l'utilisateur (login, paiement, etc.).
  • Minimisez le nombre de tests E2E pour éviter des tests longs et coûteux.
  • Automatisez les tests dans un pipeline CI/CD pour détecter les régressions.
  • Nettoyez les données après chaque test pour garantir l'indépendance des scénarios.

Tendances actuelles

Les tests E2E deviennent de plus en plus populaires grâce à des outils modernes comme Cypress qui simplifient leur implémentation et leur maintenance. Ces outils offrent des fonctionnalités comme les captures d'écran et les vidéos des tests pour faciliter le débogage.

Vue.js : Vue Test Utils

Introduction

Vue Test Utils est une bibliothèque officielle de Vue.js conçue pour simplifier le test unitaire des composants Vue. Elle permet de monter, manipuler et interagir avec des composants de manière isolée pour s'assurer qu'ils fonctionnent comme prévu.

Cette bibliothèque est compatible avec des frameworks de tests comme Jest ou Mocha, ce qui la rend flexible et facile à intégrer dans un projet Vue.js.

Pourquoi utiliser Vue Test Utils ?

  • Simuler les interactions utilisateur (clics, saisie, etc.).
  • Vérifier les sorties rendues par un composant.
  • Tester les comportements des méthodes, des événements et des propriétés réactives.

Installation

// Installation de Vue Test Utils
npm install @vue/test-utils --save-dev

// Installation de Jest pour exécuter les tests
npm install jest @vue/test-utils --save-dev
        

Exemple de test

Voici un exemple simple de test d'un composant Vue avec Vue Test Utils et Jest.

// Composant : HelloWorld.vue



        
// Test du composant avec Vue Test Utils
import { mount } from '@vue/test-utils';
import HelloWorld from './HelloWorld.vue';

describe('HelloWorld.vue', () => {
    it('affiche le message initial', () => {
        const wrapper = mount(HelloWorld);
        expect(wrapper.text()).toContain('Bonjour Vue.js!');
    });

    it('change le message après un clic', async () => {
        const wrapper = mount(HelloWorld);
        const button = wrapper.find('button');
        await button.trigger('click');
        expect(wrapper.text()).toContain('Message mis à jour!');
    });
});
        

Bonnes pratiques

  • Testez uniquement la logique interne et les interactions utilisateur spécifiques au composant.
  • Évitez de tester des fonctionnalités qui relèvent d'autres niveaux de tests (comme les API ou le DOM natif).
  • Utilisez des mocks pour les dépendances externes comme les services ou les stores Vuex.
  • Organisez les tests par composant pour une meilleure maintenabilité.

Tendances actuelles

Les tests unitaires avec Vue Test Utils sont devenus essentiels pour les projets Vue.js modernes. La communauté Vue propose de plus en plus de plugins et d'extensions pour faciliter le test des composants complexes, comme ceux utilisant des animations, des transitions ou des fonctionnalités avancées de Vue 3.

Sommaire : Outils pour Vue.js

  • Vue CLI - Gestionnaire de projets Vue.js.
  • Vite - Alternative rapide et moderne à Vue CLI.
  • Vue Devtools - Extension de navigateur pour déboguer et explorer vos projets Vue.js.

Vue.js : Outils

Introduction

Vue.js est soutenu par un écosystème riche en outils qui simplifient la création, le développement et le débogage de vos projets. Ces outils permettent de gérer les configurations complexes, d'améliorer les performances du développement et d'analyser en profondeur les comportements de vos applications.

Points forts des outils Vue.js

  • Productivité accrue : Automatisation des tâches courantes comme la création de projets et le rechargement en direct.
  • Expérience de débogage améliorée : Avec Vue Devtools, explorez les états et les mutations de vos composants.
  • Flexibilité : Les outils comme Vue CLI et Vite s'adaptent à des projets simples ou complexes.

Pourquoi utiliser ces outils ?

  • Simplifier la gestion des dépendances et des configurations.
  • Améliorer l'efficacité du développement avec des optimisations spécifiques à Vue.js.
  • Assurer une meilleure qualité de code grâce aux outils de test et de débogage intégrés.

Ces outils sont conçus pour répondre aux besoins des développeurs modernes, qu'il s'agisse de prototypage rapide, de déploiement à grande échelle ou d'amélioration continue des performances.

Vue CLI : Gestionnaire de Projets Vue.js

Introduction

Vue CLI (Command Line Interface) est un outil en ligne de commande conçu pour simplifier la création et la gestion des projets Vue.js. Il offre une structure de projet optimisée avec des configurations par défaut adaptées à la plupart des cas d'utilisation.

Vue CLI permet d'intégrer facilement des outils modernes comme Babel, TypeScript, ESLint, et bien d'autres. Il est également extensible, ce qui le rend adapté à des projets simples comme à des applications complexes.

Points Clés

  • Productivité : Créez rapidement un projet préconfiguré.
  • Extensibilité : Ajoutez des plugins pour adapter votre projet à vos besoins.
  • Compatibilité : Supporte les outils modernes comme TypeScript et les Progressive Web Apps (PWA).

Installation

Pour utiliser Vue CLI, vous devez avoir Node.js et npm installés sur votre machine. Installez Vue CLI globalement en exécutant la commande suivante :

// Installation globale de Vue CLI
npm install -g @vue/cli
        

Une fois installé, vous pouvez vérifier la version de Vue CLI avec :

// Vérification de la version
vue --version
        

Création d'un Projet

Pour créer un nouveau projet avec Vue CLI, utilisez la commande suivante :

// Création d'un projet
vue create mon-projet
        

Pendant la création, Vue CLI vous demandera de choisir une configuration. Vous pouvez opter pour la configuration par défaut ou personnaliser votre projet en sélectionnant les fonctionnalités comme TypeScript, Vuex, Router, etc.

Gestion des Plugins

Vue CLI utilise un système de plugins pour gérer les fonctionnalités supplémentaires. Vous pouvez ajouter des plugins à votre projet à tout moment avec la commande suivante :

// Ajouter un plugin
vue add plugin-name
        

Exemples de plugins populaires :

  • PWA Plugin : Ajoute des fonctionnalités pour les Progressive Web Apps.
  • Vue Router : Configure le routage dans votre projet.
  • Vuex : Ajoute une gestion d'état globale.

Lancer le Projet

Une fois le projet créé, vous pouvez démarrer le serveur de développement avec :

// Démarrage du serveur de développement
npm run serve
        

Par défaut, votre projet sera accessible sur http://localhost:8080.

Bonnes Pratiques

  • Utilisez vue.config.js pour personnaliser les configurations du projet.
  • Documentez les plugins installés pour faciliter la collaboration en équipe.
  • Testez régulièrement votre application avec des scripts comme npm run build.

Tendances Actuelles

Vue CLI reste un outil populaire pour les projets Vue.js, mais des alternatives comme Vite gagnent en traction grâce à leurs performances accrues. Cependant, Vue CLI reste pertinent pour les projets nécessitant des configurations avancées ou une compatibilité avec des outils spécifiques.

Vite : Gestionnaire Ultra-Rapide pour Vue.js

Introduction

Vite est un gestionnaire de projet de nouvelle génération conçu pour les frameworks modernes comme Vue.js. Il se distingue par sa rapidité exceptionnelle, obtenue grâce à l'utilisation de ESBuild pour le bundling et à son architecture basée sur les modules ES natifs (ESM).

Contrairement à Vue CLI, qui utilise Webpack, Vite propose un système de compilation instantanée pour le développement, rendant l'expérience de codage plus fluide et réactive.

Points Clés

  • Performance : Temps de démarrage quasi-instantané.
  • Simplicité : Configuration minimale nécessaire.
  • Support natif : Compatible avec Vue 3, TypeScript, JSX, et plus encore.

Installation

Pour démarrer avec Vite, vous devez avoir Node.js installé sur votre machine. Utilisez la commande suivante pour créer un nouveau projet Vue.js avec Vite :

// Création d'un projet avec Vite
npm create vite@latest mon-projet --template vue
        

Pendant l'installation, Vite vous demandera de choisir un nom de projet. Une fois terminé, accédez au répertoire du projet et installez les dépendances :

// Installation des dépendances
cd mon-projet && npm install
        

Lancer le Serveur de Développement

Pour lancer le serveur de développement, exécutez :

// Démarrer le serveur de développement
npm run dev
        

Par défaut, votre application sera accessible sur http://localhost:5173.

Configuration

Vite est livré avec une configuration par défaut qui fonctionne pour la plupart des projets. Cependant, vous pouvez personnaliser votre projet en modifiant le fichier vite.config.js. Exemple :

// Exemple de configuration vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [vue()],
    server: {
        port: 3000, // Changer le port par défaut
        open: true // Ouvre automatiquement le navigateur
    },
    build: {
        outDir: 'dist', // Répertoire de sortie
        minify: 'esbuild' // Utilise esbuild pour minimiser le code
    }
});
        

Intégration avec Vue 3

Vite intègre directement le plugin Vue.js pour gérer les fichiers .vue. Vous pouvez également ajouter des fonctionnalités comme TypeScript ou JSX en installant des plugins supplémentaires.

Bonnes Pratiques

  • Utilisez des alias pour simplifier les importations dans vite.config.js.
  • Activez le mode Hot Module Replacement (HMR) pour une expérience de développement plus fluide.
  • Documentez les scripts personnalisés dans le fichier package.json.

Tendances Actuelles

Vite est en train de devenir l'outil standard pour le développement avec Vue.js grâce à sa rapidité et sa simplicité. Il est de plus en plus adopté par les développeurs pour les projets modernes où la performance et la réactivité sont prioritaires.

Vue Devtools : Outil de Débogage Puissant pour Vue.js

Introduction

Vue Devtools est une extension pour les navigateurs modernes (Chrome, Firefox) conçue pour aider les développeurs à déboguer leurs applications Vue.js. Il offre une interface intuitive pour explorer l'arbre des composants, surveiller l'état, analyser les événements, et bien plus encore.

Cet outil est particulièrement utile pour comprendre et diagnostiquer les problèmes dans des applications Vue.js complexes.

Points Clés

  • Permet de visualiser la hiérarchie des composants.
  • Affiche les propriétés réactives (data, computed, props).
  • Capture et analyse les événements émis par les composants.
  • Supporte Vue Router et Vuex pour une inspection approfondie.

Installation

Installation pour Navigateurs

Vue Devtools est disponible en tant qu'extension pour les principaux navigateurs :

Utilisation avec des Serveurs Locaux

Si votre application fonctionne en mode production ou dans un environnement local sécurisé (HTTPS), vous devrez activer Vue Devtools manuellement. Ajoutez ce script à votre projet :

// Activer Vue Devtools en local
import { createApp } from 'vue';

const app = createApp(App);

// Active Vue Devtools
if (process.env.NODE_ENV === 'development') {
    app.config.devtools = true;
}

app.mount('#app');
        

Fonctionnalités

Inspection de l'Arbre des Composants

Vue Devtools affiche une vue hiérarchique des composants utilisés dans votre application. Chaque composant peut être sélectionné pour examiner ses propriétés réactives comme :

  • data
  • props
  • computed
  • methods

Surveillance de Vuex

Pour les projets utilisant Vuex, Vue Devtools offre un onglet dédié à l'inspection des state, getters, et mutations. Vous pouvez également visualiser l'historique des mutations.

Intégration Vue Router

Si votre application utilise Vue Router, Devtools affiche l'état de la route actuelle, les paramètres, et l'historique de navigation.

Bonnes Pratiques

  • Utilisez Vue Devtools pour surveiller l'état en temps réel.
  • Activez les options de développement dans main.js pour un débogage plus précis.
  • Documentez les changements observés dans les mutations ou les événements.

Tendances Actuelles

Vue Devtools reste un outil incontournable pour les développeurs Vue.js, et ses fonctionnalités s'élargissent régulièrement. Il est également utilisé dans des bibliothèques associées comme Pinia (gestion d'état) et Nuxt.js.

Miscellaneous

Cette section couvre des sujets divers qui ne sont pas directement liés aux concepts fondamentaux de Vue.js mais qui jouent un rôle clé dans la création d'applications robustes, performantes et conviviales.

Sommaire

Introduction

Bien que Vue.js se concentre principalement sur la construction de composants et la gestion de l'état, certains aspects avancés et pratiques permettent d'améliorer considérablement vos projets. Ces fonctionnalités ajoutent de la flexibilité et augmentent les possibilités d'optimisation et de personnalisation.

Voici un aperçu des thèmes abordés dans cette section :

  • Performance Optimization : Techniques pour rendre vos applications plus rapides et efficaces.
  • Plugins : Utilisation et création de plugins pour étendre les fonctionnalités de Vue.
  • Internationalization (i18n) : Prise en charge de plusieurs langues dans vos applications.
  • SSR Overview : Rappel des concepts de rendu côté serveur pour les applications Vue.js.

Cette section est idéale pour les développeurs qui souhaitent affiner leurs compétences et explorer les outils et techniques avancés liés à Vue.js.

Performance Optimization

Introduction

L'optimisation des performances est essentielle pour garantir que vos applications Vue.js restent réactives, rapides et efficaces, même avec des données volumineuses ou des utilisateurs simultanés. Cette section aborde les meilleures pratiques et techniques pour améliorer les performances de vos applications.

Avec Vue.js, vous bénéficiez déjà d'un moteur de rendu efficace, mais une mauvaise gestion des composants, des données ou des événements peut affecter les performances. Il est donc crucial d'adopter une approche proactive pour identifier et résoudre les goulots d'étranglement.

Bonnes pratiques générales

  • Utilisez des composants dynamiques (v-if ou v-show) judicieusement pour afficher ou masquer des éléments.
  • Préférez v-for avec une clé unique (key) pour assurer un suivi correct des éléments de liste.
  • Adoptez des techniques de virtualisation pour les longues listes (ex : vue-virtual-scroller).
  • Limitez les observateurs réactifs (watch) et les calculs complexes dans les propriétés calculées (computed).
  • Minimisez les mises à jour DOM en regroupant les changements.

Techniques avancées

  • Utilisez Lazy Loading pour les composants et les ressources, en chargeant les parties de l'application uniquement lorsqu'elles sont nécessaires.
  • Implémentez Code Splitting avec des outils comme Webpack ou Vite pour réduire la taille initiale de votre application.
  • Appliquez le Debouncing et le Throttling aux événements utilisateur intensifs comme le défilement ou la saisie.
  • Activez le mode production pour réduire la taille du bundle final et améliorer les performances.

Exemple Pratique : Lazy Loading

Voici un exemple de mise en œuvre du Lazy Loading pour un composant Vue :

// Importation paresseuse d'un composant
const UserProfile = () => import('./components/UserProfile.vue');

export default {
    components: {
        UserProfile
    }
};
        

Outils pour surveiller les performances

  • Vue Devtools : Identifiez les goulots d'étranglement dans les composants.
  • Lighthouse : Analysez les performances globales de votre application, y compris le temps de chargement et l'interactivité.
  • Webpack Bundle Analyzer : Vérifiez la taille des bundles et optimisez-les.

Bonnes pratiques spécifiques à Vue.js

  • Utilisez des directives comme v-once pour limiter le rendu inutile des éléments statiques.
  • Préférez functional components si votre composant ne nécessite pas de réactivité.
  • Activez les fragments dans Vue 3 pour éviter les éléments DOM inutiles.

Tendances actuelles

L'optimisation des performances front-end évolue avec de nouveaux outils comme Vite et des frameworks comme Astro, qui mettent l'accent sur le rendu côté serveur et l'hydratation partielle. Ces techniques offrent une meilleure expérience utilisateur tout en réduisant les coûts de calcul.

Vue.js : Plugins

Introduction

Les plugins sont une partie intégrale de l'écosystème Vue.js, permettant d'étendre les fonctionnalités de base de Vue. Ils fournissent une méthode pour encapsuler des fonctionnalités globales, comme des bibliothèques tierces, des mixins, ou des directives personnalisées, et les rendre disponibles dans toute l'application.

L'utilisation de plugins dans Vue.js est simple et repose sur la méthode app.use(). Une fois intégré, un plugin peut ajouter des options globales, des composants, des directives, ou des méthodes au prototype de Vue.

Points clés

  • Les plugins permettent une utilisation globale de fonctionnalités sans les importer manuellement dans chaque composant.
  • Ils peuvent encapsuler la logique complexe ou la configuration, rendant le code plus propre et modulaire.
  • Les plugins personnalisés peuvent être créés pour répondre à des besoins spécifiques.

Syntaxe et Utilisation

La création et l'utilisation d'un plugin suivent une structure simple :

// Création d'un plugin simple
export default {
    install(app, options) {
        // Ajoute une méthode globale
        app.config.globalProperties.$maFonction = () => {
            console.log('Fonctionnalité du plugin activée.');
        };

        // Enregistre un composant global
        app.component('MonPluginComponent', {
            template: `<div>Composant du plugin</div>`
        });
    }
};
        
// Utilisation du plugin
import { createApp } from 'vue';
import MonPlugin from './mon-plugin';

// Création de l'application Vue
const app = createApp(App);

// Utilisation du plugin
app.use(MonPlugin);
app.mount('#app');
        

Plugins populaires dans l'écosystème Vue.js

  • Vue Router : Gestion de la navigation et des routes dans une application Vue.
  • Vuex : Gestion centralisée de l'état de l'application.
  • Vue I18n : Support de l'internationalisation.
  • Vue Toastification : Notifications stylées et réactives.

Bonnes Pratiques

  • Utilisez les plugins uniquement lorsque des fonctionnalités globales sont nécessaires pour éviter une surcharge inutile.
  • Créez des plugins modulaires et réutilisables pour les fonctionnalités partagées entre plusieurs projets.
  • Documentez clairement les options ou les paramètres nécessaires pour l'utilisation du plugin.
  • Privilégiez les plugins maintenus régulièrement pour bénéficier des dernières fonctionnalités et correctifs.

Tendances actuelles

Avec Vue 3, l'écosystème des plugins a évolué pour tirer parti des nouvelles fonctionnalités comme la Composition API et les Fragments. Les plugins modernes adoptent ces concepts pour offrir une expérience plus flexible et performante.

Vue.js : Internationalization (i18n)

Introduction

L'internationalisation (i18n) est essentielle pour créer des applications accessibles à un public mondial. Avec Vue.js, vous pouvez facilement gérer la traduction des interfaces utilisateur, les formats de date et d'heure, ou encore les nombres spécifiques à une région grâce à des bibliothèques comme Vue I18n.

Vue I18n est une solution complète et intégrée dans l'écosystème Vue pour gérer les traductions et les localisations. Elle prend en charge :

  • La gestion des messages traduits.
  • Le formatage des dates, nombres et devises.
  • Le choix dynamique de la langue à partir des préférences de l'utilisateur.

Points Clés

  • Organisez vos fichiers de traduction par langue pour une gestion facile.
  • Privilégiez des clés descriptives pour vos messages traduits.
  • Utilisez des outils comme Vue I18n CLI pour générer des fichiers de traduction.

Configuration et Utilisation de Vue I18n

1. Installation de Vue I18n

Ajoutez la bibliothèque Vue I18n à votre projet en utilisant npm ou yarn :

// Installation via npm
npm install vue-i18n
        

2. Configuration de base

Configurez Vue I18n dans votre projet :

// i18n.js
import { createI18n } from 'vue-i18n';

// Définition des messages
const messages = {
    en: {
        welcome: 'Welcome to Vue.js!'
    },
    fr: {
        welcome: 'Bienvenue sur Vue.js!'
    }
};

// Configuration d'i18n
const i18n = createI18n({
    locale: 'en', // Langue par défaut
    fallbackLocale: 'en', // Langue de secours
    messages
});

export default i18n;
        

3. Intégration dans Vue

Intégrez Vue I18n dans votre application :

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import i18n from './i18n';

// Création de l'application avec i18n
const app = createApp(App);
app.use(i18n);
app.mount('#app');
        

Exemple Pratique

// App.vue
<template>
    <div>
        <p>{{ $t('welcome') }}</p>
        <button @click='changeLanguage'>Changer de Langue</button>
    </div>
</template>

<script>
export default {
    methods: {
        changeLanguage() {
            this.$i18n.locale = this.$i18n.locale === 'en' ? 'fr' : 'en';
        }
    }
};
</script>
        

Bonnes Pratiques

  • Organisez vos messages dans des fichiers séparés par langue pour une maintenance facile.
  • Privilégiez des clés claires et descriptives pour vos messages traduits.
  • Utilisez fallbackLocale pour gérer les langues manquantes.
  • Testez votre application pour garantir une bonne expérience utilisateur dans chaque langue.

Conclusion sur Vue.js

Résumé

Vue.js est un framework JavaScript puissant, flexible et intuitif qui permet de créer des interfaces utilisateur dynamiques et réactives. Grâce à son approche progressive, il peut être utilisé aussi bien pour des projets simples que pour des applications complexes. Les concepts clés comme la Composition API, les directives, le routing, et la gestion de l'état avec Vuex permettent de structurer efficacement le code et de le rendre maintenable à long terme.

Que vous soyez un développeur débutant ou expérimenté, Vue.js offre un écosystème complet et des outils adaptés à tous les niveaux de compétences.

Points Forts de Vue.js

  • Apprentissage rapide : Une syntaxe simple et intuitive.
  • Flexibilité : Adaptable à divers besoins, qu'il s'agisse d'un simple widget ou d'une SPA.
  • Écosystème robuste : Avec Vue Router, Vuex, et une communauté active, Vue.js est bien équipé pour les projets modernes.
  • Performances : Léger et optimisé pour des rendus rapides.
  • Documentation exceptionnelle : Guide clair et détaillé pour tous les concepts.

Perspectives

Vue.js continue de croître et d'évoluer, notamment avec l'intégration des meilleures pratiques modernes comme la Composition API et le support de TypeScript. Son adoption par de grandes entreprises et sa compatibilité avec des outils comme Vite et Nuxt.js renforcent sa position comme choix incontournable pour le développement d'applications web modernes.

En vous investissant dans Vue.js, vous vous équipez d'un outil durable et performant pour construire des expériences utilisateur de qualité.

Derniers Conseils

  • Commencez avec de petits projets pour bien maîtriser les concepts de base.
  • Apprenez à utiliser efficacement l'écosystème, notamment Vue Router, Vuex (ou Pinia), et Vue Devtools.
  • Adoptez des pratiques modernes comme la Composition API pour une meilleure lisibilité et modularité.
  • Participez à la communauté Vue.js pour rester à jour avec les nouvelles tendances et partager vos expériences.

Étapes Suivantes

Maintenant que vous avez exploré Vue.js en détail, il est temps de passer à la pratique ! Créez votre propre projet, intégrez des fonctionnalités avancées, et mettez en œuvre les concepts appris dans ce cours. N'oubliez pas de tester et optimiser votre application pour offrir la meilleure expérience utilisateur possible.

Avec Vue.js, les possibilités sont infinies. Bonne chance et bon développement !