Introduction à la Composition API Vue.js : setup(), ref() et reactive()

Découvrez la Composition API de Vue 3. Maîtrisez setup(), ref() pour les primitives et reactive() pour les objets avec des exemples pratiques.

Mahmoud DEVO
Mahmoud DEVO
December 28, 2025 11 min read
Introduction à la Composition API Vue.js : setup(), ref() et reactive()
Table of Contents

Introduction

La Composition API représente l’une des évolutions les plus significatives de Vue.js depuis sa création. Introduite avec Vue 3, elle offre une nouvelle façon d’organiser et de structurer le code de vos composants. Contrairement à l’Options API traditionnelle qui organise le code par type d’option (data, methods, computed, watch), la Composition API permet de regrouper la logique par fonctionnalité.

Dans cet article approfondi, nous explorerons en détail les concepts fondamentaux de la Composition API : la fonction setup(), les refs avec ref(), et les objets réactifs avec reactive(). Nous verrons également des fonctions complémentaires essentielles comme toRef(), toRefs(), readonly(), et bien d’autres.

Pourquoi la Composition API existe-t-elle ?

Les limitations de l’Options API

Avant Vue 3, l’Options API était la seule façon d’écrire des composants Vue. Bien qu’elle soit intuitive pour les débutants, elle présente plusieurs limitations :

  1. Fragmentation du code : La logique liée à une même fonctionnalité est dispersée entre data, methods, computed, et watch.

  2. Réutilisation difficile : Partager de la logique entre composants nécessitait des mixins, qui posent des problèmes de collision de noms et de source peu claire.

  3. Support TypeScript limité : L’inférence de types dans l’Options API est complexe car this peut référencer de nombreuses propriétés.

  4. Composants volumineux : Les grands composants deviennent difficiles à maintenir car la logique est éclatée.

Les avantages de la Composition API

La Composition API résout ces problèmes en offrant :

  • Organisation par fonctionnalité : Regroupez tout le code lié à une fonctionnalité au même endroit.
  • Réutilisation via les composables : Créez des fonctions réutilisables facilement.
  • Meilleur support TypeScript : L’inférence de types fonctionne naturellement.
  • Flexibilité : Utilisez uniquement les fonctionnalités dont vous avez besoin.
// Options API - logique dispersée
export default {
  data() {
    return {
      count: 0,
      user: null
    }
  },
  computed: {
    doubleCount() {
      return this.count * 2
    }
  },
  methods: {
    increment() {
      this.count++
    },
    fetchUser() {
      // logique utilisateur
    }
  },
  watch: {
    count(newVal) {
      console.log('Count changed:', newVal)
    }
  }
}

// Composition API - logique regroupée
import { ref, computed, watch } from 'vue'

export default {
  setup() {
    // Logique du compteur - tout au même endroit
    const count = ref(0)
    const doubleCount = computed(() => count.value * 2)
    const increment = () => count.value++
    watch(count, (newVal) => console.log('Count changed:', newVal))

    // Logique utilisateur - séparée
    const user = ref(null)
    const fetchUser = () => { /* ... */ }

    return { count, doubleCount, increment, user, fetchUser }
  }
}

La fonction setup() en profondeur

Qu’est-ce que setup() ?

La fonction setup() est le point d’entrée de la Composition API. Elle s’exécute avant la création du composant, avant même que data, computed, ou methods ne soient résolus. C’est dans cette fonction que vous définissez l’état réactif, les fonctions, et les propriétés calculées de votre composant.

export default {
  name: "MonComposant",
  setup() {
    // Tout le code de la Composition API va ici
    // Exécuté avant la création du composant

    return {
      // Ce qui est retourné est accessible dans le template
    }
  }
}

Les arguments de setup()

La fonction setup() reçoit deux arguments importants : props et context.

L’argument props

Le premier argument contient les props passées au composant. Ces props sont réactives et seront mises à jour lorsque de nouvelles props sont passées.

export default {
  name: "ProfilUtilisateur",
  props: {
    userId: {
      type: Number,
      required: true
    },
    showDetails: {
      type: Boolean,
      default: false
    }
  },
  setup(props) {
    // Accès aux props
    console.log('ID Utilisateur:', props.userId)
    console.log('Afficher détails:', props.showDetails)

    // ATTENTION : Ne pas déstructurer les props directement
    // car cela perdrait la réactivité
    // const { userId } = props // À ÉVITER

    return {}
  }
}

L’argument context

Le second argument est un objet context qui expose trois propriétés utiles :

export default {
  name: "MonComposant",
  setup(props, context) {
    // attrs : attributs non-props passés au composant
    console.log('Attributs:', context.attrs)

    // slots : les slots passés par le parent
    console.log('Slots:', context.slots)

    // emit : fonction pour émettre des événements
    const handleClick = () => {
      context.emit('mon-evenement', { data: 'valeur' })
    }

    // expose : fonction pour exposer des propriétés publiques
    context.expose({
      maMethodePublique: () => console.log('Appelée de l\'extérieur')
    })

    return { handleClick }
  }
}

Vous pouvez également déstructurer context car il n’est pas réactif :

setup(props, { attrs, slots, emit, expose }) {
  // Utilisation directe
  emit('mon-evenement')
}

Ce que retourne setup()

La fonction setup() peut retourner un objet ou une fonction de rendu :

// Retour d'un objet (le plus courant)
setup() {
  const message = ref('Bonjour')
  const afficherMessage = () => console.log(message.value)

  return {
    message,
    afficherMessage
  }
}

// Retour d'une fonction de rendu (cas avancé)
import { h, ref } from 'vue'

setup() {
  const count = ref(0)

  return () => h('div', [
    h('p', `Compteur: ${count.value}`),
    h('button', { onClick: () => count.value++ }, 'Incrémenter')
  ])
}

ref() : la réactivité pour les primitives

Comprendre ref()

La fonction ref() crée une référence réactive qui peut contenir n’importe quelle valeur, mais elle est particulièrement utile pour les valeurs primitives (string, number, boolean).

import { ref } from 'vue'

export default {
  setup() {
    // Création de refs
    const compteur = ref(0)
    const nom = ref('Vue.js')
    const estActif = ref(true)
    const liste = ref([1, 2, 3])
    const utilisateur = ref({ nom: 'Jean', age: 30 })

    return { compteur, nom, estActif, liste, utilisateur }
  }
}

Accéder et modifier une ref

Dans le code JavaScript, vous devez utiliser .value pour accéder ou modifier la valeur d’une ref. Dans le template, Vue déroule automatiquement la ref.

import { ref } from 'vue'

export default {
  setup() {
    const message = ref('Bonjour')

    // Dans setup(), utiliser .value
    console.log(message.value) // 'Bonjour'

    const changerMessage = () => {
      message.value = 'Au revoir' // Modification avec .value
    }

    const ajouterExclamation = () => {
      message.value += '!' // Modification avec .value
    }

    return { message, changerMessage, ajouterExclamation }
  }
}
<!-- Dans le template, pas besoin de .value -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changerMessage">Changer</button>
    <button @click="ajouterExclamation">Ajouter !</button>
  </div>
</template>

Ref avec des objets

Bien que reactive() soit préféré pour les objets, ref() peut également les contenir :

import { ref } from 'vue'

export default {
  setup() {
    const utilisateur = ref({
      nom: 'Marie',
      age: 25,
      adresse: {
        ville: 'Paris',
        codePostal: '75001'
      }
    })

    // Modifier des propriétés
    const changerNom = (nouveauNom) => {
      utilisateur.value.nom = nouveauNom
    }

    // Remplacer l'objet entier
    const reinitialiser = () => {
      utilisateur.value = {
        nom: '',
        age: 0,
        adresse: { ville: '', codePostal: '' }
      }
    }

    return { utilisateur, changerNom, reinitialiser }
  }
}

reactive() : la réactivité pour les objets

Comprendre reactive()

La fonction reactive() crée un proxy réactif d’un objet. Elle est idéale pour gérer des états complexes avec plusieurs propriétés.

import { reactive } from 'vue'

export default {
  setup() {
    const etat = reactive({
      compteur: 0,
      utilisateur: {
        nom: 'Pierre',
        email: 'pierre@exemple.com'
      },
      articles: [],
      chargement: false
    })

    return { etat }
  }
}

Accéder et modifier un objet reactive

Contrairement à ref(), vous n’avez pas besoin de .value avec reactive() :

import { reactive } from 'vue'

export default {
  setup() {
    const formulaire = reactive({
      nom: '',
      email: '',
      message: '',
      erreurs: []
    })

    // Modification directe des propriétés
    const mettreAJourNom = (nom) => {
      formulaire.nom = nom
    }

    const ajouterErreur = (erreur) => {
      formulaire.erreurs.push(erreur)
    }

    const reinitialiser = () => {
      formulaire.nom = ''
      formulaire.email = ''
      formulaire.message = ''
      formulaire.erreurs = []
    }

    const soumettre = async () => {
      formulaire.erreurs = []

      if (!formulaire.nom) {
        formulaire.erreurs.push('Le nom est requis')
      }
      if (!formulaire.email) {
        formulaire.erreurs.push('L\'email est requis')
      }

      if (formulaire.erreurs.length === 0) {
        // Envoyer le formulaire
        console.log('Formulaire soumis:', { ...formulaire })
      }
    }

    return { formulaire, mettreAJourNom, ajouterErreur, reinitialiser, soumettre }
  }
}

Limitations de reactive()

Il est important de connaître les limitations de reactive() :

import { reactive } from 'vue'

export default {
  setup() {
    let etat = reactive({ compteur: 0 })

    // PROBLÈME : Réassigner perd la réactivité
    const reinitialiser = () => {
      // MAUVAIS - perd la réactivité
      etat = reactive({ compteur: 0 })
    }

    // SOLUTION : Modifier les propriétés individuellement
    const reinitialiserCorrect = () => {
      etat.compteur = 0
    }

    // Ou utiliser Object.assign
    const reinitialiserAvecAssign = () => {
      Object.assign(etat, { compteur: 0 })
    }

    return { etat, reinitialiserCorrect }
  }
}

Tableau comparatif : ref() vs reactive()

Caractéristiqueref()reactive()
Types supportésTous (primitifs et objets)Objets uniquement
Accès dans setup.value requisDirect
Accès dans templateAutomatiquement déballéDirect
RéassignationPossible via .valuePerd la réactivité
DéstructurationPerd la réactivitéPerd la réactivité
PerformanceLégèrement plus lentLégèrement plus rapide
Cas d’usageValeurs primitives, remplacement d’objetÉtats complexes, formulaires

toRef() et toRefs() : préserver la réactivité

toRef() : créer une ref depuis une propriété

toRef() crée une ref connectée à une propriété d’un objet réactif :

import { reactive, toRef } from 'vue'

export default {
  setup() {
    const utilisateur = reactive({
      nom: 'Sophie',
      age: 28,
      ville: 'Lyon'
    })

    // Créer une ref connectée à utilisateur.nom
    const nomRef = toRef(utilisateur, 'nom')

    const changerNom = (nouveau) => {
      // Modifier nomRef modifie aussi utilisateur.nom
      nomRef.value = nouveau
      console.log(utilisateur.nom) // Affiche le nouveau nom
    }

    return { utilisateur, nomRef, changerNom }
  }
}

toRefs() : déstructurer sans perdre la réactivité

toRefs() convertit toutes les propriétés d’un objet réactif en refs :

import { reactive, toRefs } from 'vue'

export default {
  setup() {
    const etat = reactive({
      compteur: 0,
      message: 'Bonjour',
      estActif: true
    })

    // Déstructuration avec toRefs() préserve la réactivité
    const { compteur, message, estActif } = toRefs(etat)

    const incrementer = () => {
      compteur.value++ // Utiliser .value car c'est maintenant une ref
    }

    // Retourner les refs individuellement
    return { compteur, message, estActif, incrementer }
  }
}

Utilisation avec les props

toRefs() est particulièrement utile pour déstructurer les props :

import { toRefs, watch } from 'vue'

export default {
  props: {
    titre: String,
    contenu: String
  },
  setup(props) {
    // Déstructurer les props en préservant la réactivité
    const { titre, contenu } = toRefs(props)

    // Maintenant vous pouvez utiliser titre et contenu comme des refs
    watch(titre, (nouveauTitre) => {
      console.log('Le titre a changé:', nouveauTitre)
    })

    return { titre, contenu }
  }
}

readonly() : créer des états immuables

Comprendre readonly()

readonly() crée une version en lecture seule d’un objet réactif ou d’une ref :

import { reactive, readonly } from 'vue'

export default {
  setup() {
    const etatOriginal = reactive({
      compteur: 0,
      utilisateur: {
        nom: 'Admin'
      }
    })

    // Créer une version en lecture seule
    const etatPublic = readonly(etatOriginal)

    // Ceci générera un avertissement en mode développement
    // etatPublic.compteur = 5 // Avertissement !

    // Mais l'original peut toujours être modifié
    const incrementer = () => {
      etatOriginal.compteur++
    }

    return { etatPublic, incrementer }
  }
}

Cas d’usage de readonly()

import { ref, readonly } from 'vue'

// Composable avec état exposé en lecture seule
function useCompteur() {
  const compteur = ref(0)

  const incrementer = () => compteur.value++
  const decrementer = () => compteur.value--
  const reinitialiser = () => compteur.value = 0

  return {
    // Exposer une version en lecture seule
    compteur: readonly(compteur),
    incrementer,
    decrementer,
    reinitialiser
  }
}

export default {
  setup() {
    const { compteur, incrementer, decrementer, reinitialiser } = useCompteur()

    // compteur.value = 100 // Impossible ! Génère un avertissement

    return { compteur, incrementer, decrementer, reinitialiser }
  }
}

shallowRef() et shallowReactive() : réactivité superficielle

shallowRef()

shallowRef() crée une ref qui ne suit que les changements de .value, pas les changements profonds :

import { shallowRef } from 'vue'

export default {
  setup() {
    const etat = shallowRef({
      donnees: {
        items: [1, 2, 3]
      }
    })

    // CECI déclenche une mise à jour (changement de .value)
    const remplacer = () => {
      etat.value = {
        donnees: {
          items: [4, 5, 6]
        }
      }
    }

    // CECI NE déclenche PAS de mise à jour (changement profond)
    const ajouterItem = () => {
      etat.value.donnees.items.push(7)
      // Pas de re-rendu automatique !
    }

    // Pour forcer la mise à jour après un changement profond
    import { triggerRef } from 'vue'
    const ajouterItemAvecMaj = () => {
      etat.value.donnees.items.push(7)
      triggerRef(etat) // Force le re-rendu
    }

    return { etat, remplacer, ajouterItem, ajouterItemAvecMaj }
  }
}

shallowReactive()

shallowReactive() crée un objet réactif qui ne suit que les propriétés de premier niveau :

import { shallowReactive } from 'vue'

export default {
  setup() {
    const etat = shallowReactive({
      niveau1: 'réactif',
      imbriqué: {
        niveau2: 'non réactif'
      }
    })

    // CECI déclenche une mise à jour
    const changerNiveau1 = () => {
      etat.niveau1 = 'nouveau'
    }

    // CECI NE déclenche PAS de mise à jour
    const changerNiveau2 = () => {
      etat.imbriqué.niveau2 = 'changé'
      // Pas de re-rendu automatique !
    }

    return { etat, changerNiveau1, changerNiveau2 }
  }
}

Quand utiliser shallow ?

  • Performance : Pour de grandes structures de données où seules les références de premier niveau changent.
  • Intégration : Lorsque vous travaillez avec des bibliothèques externes qui gèrent leur propre état.
  • Optimisation : Quand vous savez que les mutations profondes ne nécessitent pas de re-rendu.

unref() et isRef() : utilitaires pratiques

unref()

unref() retourne la valeur interne si l’argument est une ref, sinon retourne l’argument tel quel :

import { ref, unref } from 'vue'

export default {
  setup() {
    const compteur = ref(10)
    const valeurSimple = 20

    console.log(unref(compteur))     // 10 (déballé)
    console.log(unref(valeurSimple)) // 20 (inchangé)

    // Utile dans les fonctions qui acceptent ref ou valeur
    const doubler = (valeur) => {
      return unref(valeur) * 2
    }

    console.log(doubler(compteur))     // 20
    console.log(doubler(valeurSimple)) // 40

    return { compteur }
  }
}

isRef()

isRef() vérifie si une valeur est une ref :

import { ref, reactive, isRef, isReactive } from 'vue'

export default {
  setup() {
    const maRef = ref(0)
    const monReactive = reactive({ valeur: 0 })
    const simple = 42

    console.log(isRef(maRef))       // true
    console.log(isRef(monReactive)) // false
    console.log(isRef(simple))      // false

    console.log(isReactive(monReactive)) // true
    console.log(isReactive(maRef))       // false

    // Utile pour créer des fonctions génériques
    const obtenirValeur = (source) => {
      if (isRef(source)) {
        return source.value
      }
      return source
    }

    return { maRef, monReactive }
  }
}

Exemples pratiques complets

Exemple 1 : Gestionnaire de tâches

import { ref, reactive, computed } from 'vue'

export default {
  setup() {
    const nouvelleTache = ref('')
    const taches = reactive([])

    const tachesTerminees = computed(() =>
      taches.filter(t => t.terminee).length
    )

    const tachesEnCours = computed(() =>
      taches.filter(t => !t.terminee).length
    )

    const pourcentageTermine = computed(() => {
      if (taches.length === 0) return 0
      return Math.round((tachesTerminees.value / taches.length) * 100)
    })

    const ajouterTache = () => {
      if (nouvelleTache.value.trim()) {
        taches.push({
          id: Date.now(),
          texte: nouvelleTache.value.trim(),
          terminee: false,
          creeLe: new Date()
        })
        nouvelleTache.value = ''
      }
    }

    const basculerTache = (id) => {
      const tache = taches.find(t => t.id === id)
      if (tache) {
        tache.terminee = !tache.terminee
      }
    }

    const supprimerTache = (id) => {
      const index = taches.findIndex(t => t.id === id)
      if (index > -1) {
        taches.splice(index, 1)
      }
    }

    const effacerTerminees = () => {
      const indices = taches
        .map((t, i) => t.terminee ? i : -1)
        .filter(i => i > -1)
        .reverse()

      indices.forEach(i => taches.splice(i, 1))
    }

    return {
      nouvelleTache,
      taches,
      tachesTerminees,
      tachesEnCours,
      pourcentageTermine,
      ajouterTache,
      basculerTache,
      supprimerTache,
      effacerTerminees
    }
  }
}

Exemple 2 : Formulaire avec validation

import { reactive, computed, watch } from 'vue'

export default {
  setup() {
    const formulaire = reactive({
      nom: '',
      email: '',
      motDePasse: '',
      confirmationMotDePasse: ''
    })

    const erreurs = reactive({
      nom: '',
      email: '',
      motDePasse: '',
      confirmationMotDePasse: ''
    })

    const estValide = computed(() => {
      return Object.values(erreurs).every(e => e === '') &&
             Object.values(formulaire).every(v => v !== '')
    })

    // Validation du nom
    watch(() => formulaire.nom, (valeur) => {
      if (valeur.length < 2) {
        erreurs.nom = 'Le nom doit contenir au moins 2 caractères'
      } else if (valeur.length > 50) {
        erreurs.nom = 'Le nom ne peut pas dépasser 50 caractères'
      } else {
        erreurs.nom = ''
      }
    })

    // Validation de l'email
    watch(() => formulaire.email, (valeur) => {
      const regexEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
      if (!regexEmail.test(valeur)) {
        erreurs.email = 'Veuillez entrer une adresse email valide'
      } else {
        erreurs.email = ''
      }
    })

    // Validation du mot de passe
    watch(() => formulaire.motDePasse, (valeur) => {
      if (valeur.length < 8) {
        erreurs.motDePasse = 'Le mot de passe doit contenir au moins 8 caractères'
      } else if (!/[A-Z]/.test(valeur)) {
        erreurs.motDePasse = 'Le mot de passe doit contenir au moins une majuscule'
      } else if (!/[0-9]/.test(valeur)) {
        erreurs.motDePasse = 'Le mot de passe doit contenir au moins un chiffre'
      } else {
        erreurs.motDePasse = ''
      }
    })

    // Validation de la confirmation
    watch([() => formulaire.motDePasse, () => formulaire.confirmationMotDePasse],
      ([mdp, confirmation]) => {
        if (confirmation && mdp !== confirmation) {
          erreurs.confirmationMotDePasse = 'Les mots de passe ne correspondent pas'
        } else {
          erreurs.confirmationMotDePasse = ''
        }
      }
    )

    const soumettre = async () => {
      if (estValide.value) {
        console.log('Formulaire soumis:', { ...formulaire })
        // Logique d'envoi
      }
    }

    const reinitialiser = () => {
      Object.keys(formulaire).forEach(cle => {
        formulaire[cle] = ''
      })
      Object.keys(erreurs).forEach(cle => {
        erreurs[cle] = ''
      })
    }

    return { formulaire, erreurs, estValide, soumettre, reinitialiser }
  }
}

Bonnes Pratiques

1. Préférez ref() pour les valeurs simples

// BON
const compteur = ref(0)
const estCharge = ref(false)
const nomUtilisateur = ref('')

// MOINS OPTIMAL pour des valeurs simples
const etat = reactive({ compteur: 0 })

2. Utilisez reactive() pour les objets complexes

// BON pour les états complexes
const etatFormulaire = reactive({
  etape: 1,
  donnees: {},
  erreurs: [],
  enCours: false
})

// MOINS OPTIMAL
const etape = ref(1)
const donnees = ref({})
const erreurs = ref([])
const enCours = ref(false)

3. Nommez vos refs de manière descriptive

// BON
const utilisateurConnecte = ref(null)
const estEnCoursDeChargement = ref(false)
const listeArticles = ref([])

// MAUVAIS
const u = ref(null)
const loading = ref(false)
const data = ref([])

4. Groupez la logique liée ensemble

setup() {
  // --- Logique du compteur ---
  const compteur = ref(0)
  const incrementer = () => compteur.value++
  const decrementer = () => compteur.value--

  // --- Logique utilisateur ---
  const utilisateur = ref(null)
  const chargerUtilisateur = async (id) => { /* ... */ }
  const deconnecter = () => { utilisateur.value = null }

  // --- Logique panier ---
  const panier = reactive({ items: [], total: 0 })
  const ajouterAuPanier = (item) => { /* ... */ }

  return {
    compteur, incrementer, decrementer,
    utilisateur, chargerUtilisateur, deconnecter,
    panier, ajouterAuPanier
  }
}

5. Extrayez la logique réutilisable en composables

// composables/useCompteur.js
import { ref } from 'vue'

export function useCompteur(initial = 0) {
  const compteur = ref(initial)
  const incrementer = () => compteur.value++
  const decrementer = () => compteur.value--
  const reinitialiser = () => compteur.value = initial

  return { compteur, incrementer, decrementer, reinitialiser }
}

// Utilisation dans un composant
import { useCompteur } from '@/composables/useCompteur'

export default {
  setup() {
    const { compteur, incrementer, decrementer } = useCompteur(10)
    return { compteur, incrementer, decrementer }
  }
}

6. Utilisez readonly() pour protéger les états

import { ref, readonly } from 'vue'

export function useEtatGlobal() {
  const etat = ref({ utilisateur: null, theme: 'clair' })

  const setUtilisateur = (user) => { etat.value.utilisateur = user }
  const setTheme = (theme) => { etat.value.theme = theme }

  return {
    etat: readonly(etat), // Empêche les modifications directes
    setUtilisateur,
    setTheme
  }
}

Pièges Courants à Éviter

1. Oublier .value dans le code JavaScript

// MAUVAIS - ne fonctionne pas
const compteur = ref(0)
const incrementer = () => compteur++ // Incrémente la ref, pas la valeur !

// BON
const incrementer = () => compteur.value++

2. Déstructurer et perdre la réactivité

// MAUVAIS - perd la réactivité
const etat = reactive({ nom: 'Vue', version: 3 })
const { nom, version } = etat // nom et version ne sont plus réactifs !

// BON - utiliser toRefs
const { nom, version } = toRefs(etat)

3. Réassigner un objet reactive

// MAUVAIS - perd la réactivité
let etat = reactive({ compteur: 0 })
etat = reactive({ compteur: 1 }) // La réactivité est perdue !

// BON - modifier les propriétés
etat.compteur = 1

// Ou utiliser ref si vous devez remplacer l'objet
const etat = ref({ compteur: 0 })
etat.value = { compteur: 1 } // Fonctionne correctement

4. Utiliser reactive avec des primitives

// MAUVAIS - ne fonctionne pas
const compteur = reactive(0) // Erreur ou comportement inattendu

// BON
const compteur = ref(0)

5. Mélanger Options API et Composition API de manière confuse

// CONFUS - difficile à maintenir
export default {
  data() {
    return { optionData: 'valeur' }
  },
  setup() {
    const compositionData = ref('autre valeur')
    return { compositionData }
  },
  methods: {
    maMethode() {
      // Accès à this.optionData ET this.compositionData
    }
  }
}

// PRÉFÉRÉ - utiliser l'un ou l'autre de manière cohérente
export default {
  setup() {
    const donnees = ref('valeur')
    const autreDonnees = ref('autre valeur')
    const maMethode = () => { /* ... */ }

    return { donnees, autreDonnees, maMethode }
  }
}

Conclusion

La Composition API de Vue 3 représente une évolution majeure dans la façon d’écrire des composants Vue. En maîtrisant les concepts fondamentaux que nous avons explorés dans cet article, vous serez en mesure de :

  • Organiser votre code de manière logique et maintenable en regroupant la logique par fonctionnalité.
  • Créer des composables réutilisables qui peuvent être partagés entre plusieurs composants.
  • Profiter d’un meilleur support TypeScript grâce à une inférence de types naturelle.
  • Optimiser les performances en utilisant les bonnes primitives de réactivité selon vos besoins.

Pour résumer les points clés :

  • Utilisez ref() pour les valeurs primitives et quand vous devez remplacer l’objet entier.
  • Utilisez reactive() pour les objets complexes avec plusieurs propriétés.
  • Utilisez toRef() et toRefs() pour préserver la réactivité lors de la déstructuration.
  • Utilisez readonly() pour protéger les états exposés publiquement.
  • Utilisez shallowRef() et shallowReactive() pour optimiser les performances avec de grandes structures de données.

Étapes Suivantes

Pour approfondir vos connaissances sur la Composition API :

  1. Explorez les hooks de cycle de vie : onMounted(), onUpdated(), onUnmounted(), etc.
  2. Maîtrisez les propriétés calculées avec computed() et ses options avancées.
  3. Apprenez les watchers : watch() et watchEffect() pour réagir aux changements.
  4. Créez vos propres composables en extrayant la logique commune de vos composants.
  5. Explorez le script setup : la syntaxe <script setup> qui simplifie encore plus l’écriture des composants.
  6. Intégrez TypeScript pour un typage fort et une meilleure expérience de développement.

La Composition API n’est pas qu’une alternative à l’Options API, c’est un outil puissant qui vous permettra d’écrire du code Vue plus propre, plus réutilisable et plus facile à maintenir.

Advertisement

In-Article Ad

Dev Mode

Share this article

Mahmoud DEVO

Mahmoud DEVO

Senior Full-Stack Developer

I'm a passionate full-stack developer with 10+ years of experience building scalable web applications. I write about Vue.js, Node.js, PostgreSQL, and modern DevOps practices.

Enjoyed this article?

Subscribe to get more tech content delivered to your inbox.

Related Articles