
Vue 3 : Composition API ou Options API, à quoi sert vraiment chacune
- vuetelemetry
- Guides
- 6 min de lecture
La Composition API ne remplace pas l'Options API. Elles répondent à des problèmes différents, à des échelles différentes, et le choix dépend moins de la nouveauté que de la façon dont votre composant grandit. Ce que fait chacune, où chacune atteint ses limites, et comment choisir sans réécrire du code qui fonctionne.
Vue 3 fournit les deux API. L'Options API est celle que Vue a toujours eue : un composant est un objet dont `data`, `computed`, `methods`, `watch` et les hooks de cycle de vie sont des propriétés nommées. La Composition API, arrivée avec Vue 3, permet d'écrire la même logique sous forme de fonctions ordinaires, dans une fonction `setup()` ou un bloc `<script setup>`. Aucune n'est dépréciée, et aucune n'est appelée à disparaître.
L'Options API range le code par type d'option. Tout l'état réactif va dans `data()`. Toutes les valeurs calculées vont dans `computed`. Toutes les méthodes vont dans `methods`. C'est clair pour un petit composant, parce que chaque sujet tient en quelques lignes par section et qu'on parcourt les sections d'un coup d'œil. Cela devient un problème quand le composant grossit : une seule fonctionnalité (un filtre de recherche, par exemple) a son état dans `data`, ses valeurs dérivées dans `computed`, ses gestionnaires d'événements dans `methods` et son initialisation dans `mounted`. Elle est éparpillée à quatre endroits du fichier.
Comment l'Options API organise le code

La Composition API range le code par préoccupation logique. Au lieu de mettre tout l'état à un endroit et toutes les méthodes à un autre, on regroupe l'état, les valeurs calculées, les watchers et les fonctions qui appartiennent à une même fonctionnalité. Un filtre de recherche devient un bloc de 15 lignes qui contient tout ce dont il a besoin. La pagination devient un autre bloc. Ils se suivent dans le fichier, et on peut lire l'un sans sauter vers trois autres sections.
Cela ne compte que pour les gros composants. Un composant avec un état, une valeur calculée et une méthode est aussi lisible dans l'une que dans l'autre API. La Composition API commence à payer quand un composant porte trois préoccupations indépendantes ou plus, car c'est à partir de là que l'Options API oblige à entremêler de la logique sans rapport entre les sections.
Comment la Composition API organise le code
`<script setup>` est la syntaxe qu'utilise la plupart du nouveau code Vue 3. C'est un raccourci de compilation qui évite d'écrire une fonction `setup()` explicite et son instruction de retour. Les variables déclarées au premier niveau sont directement disponibles dans le template. Les props se déclarent avec `defineProps()` et les événements avec `defineEmits()`. Ce sont deux macros du compilateur, qu'il n'est pas nécessaire d'importer.
- L'Options API range le code par type (data, computed, methods) ; la Composition API le range par fonctionnalité
- Aucune des deux API n'est dépréciée, et les deux reposent sur le même système de réactivité
- ref() est le choix par défaut recommandé plutôt que reactive(), pour éviter les bugs de réaffectation et de déstructuration
- Les composables remplacent les mixins pour réutiliser de la logique entre composants, sans collision de noms
- L'inférence TypeScript fonctionne naturellement avec la Composition API et peine avec le this de l'Options API
- La migration est facultative : les deux API cohabitent dans le même projet, et même dans le même composant
La réactivité de la Composition API repose sur `ref()` et `reactive()`. `ref()` enveloppe une valeur unique et demande `.value` pour la lire ou l'écrire en JavaScript (mais pas dans le template, où Vue la déballe automatiquement). `reactive()` enveloppe un objet, dont les propriétés sont réactives sans `.value`. La source de bugs la plus fréquente est d'oublier `.value` dans le script, ou de l'écrire dans le template où il n'a rien à faire.
ref, reactive et script setup
`ref()` est presque toujours le bon choix par défaut. `reactive()` a deux restrictions qui piègent souvent. D'abord, on ne peut pas réaffecter l'objet entier (le proxy porte sur la référence d'origine, pas sur la variable). Ensuite, déstructurer un objet réactif fait perdre la réactivité aux propriétés extraites. `ref()` n'a aucun de ces deux problèmes, et le prix de `.value` est faible comparé au temps de débogage de ces cas limites.
Les composables sont le principal avantage structurel. Un composable est une fonction qui utilise les primitives de la Composition API (`ref`, `computed`, `watch`, `onMounted`) et renvoie un état réactif. `useMouse()`, `useFetch()` et `useLocalStorage()` en sont des exemples typiques. On les appelle dans `setup()` et on récupère des valeurs réactives. C'est le schéma que l'Options API ne sait pas reproduire proprement : les mixins partagent de la logique entre composants, mais ils fusionnent les propriétés par leur nom, ce qui crée des collisions silencieuses et empêche de savoir d'où vient une propriété.
Les mixins sont l'équivalent côté Options API, et ils posent problème à grande échelle. Si deux mixins définissent une propriété `data` du même nom, l'une l'emporte sans prévenir. Si un mixin ajoute une méthode, le composant n'en porte aucune déclaration visible. L'origine d'une propriété devient ambiguë à mesure que les mixins s'ajoutent. La documentation de Vue recommande explicitement les composables plutôt que les mixins pour réutiliser de la logique en Vue 3.
Composables contre mixins
Le support de TypeScript est nettement meilleur avec la Composition API. L'Options API demande l'enveloppe `defineComponent()`, et l'inférence de types passe par un type `this` complexe qui peine sur certains schémas (callbacks imbriqués, fonctions externes qui lisent l'état du composant). La Composition API utilise des variables ordinaires avec des types TypeScript standard. `ref<number>(0)` donne un `Ref<number>`. Les composables ont des valeurs de retour typées. L'aide de l'IDE (autocomplétion, types au survol, refactorisation) fonctionne comme pour n'importe quelle fonction TypeScript.
Les performances à l'exécution sont proches, avec deux avantages documentés pour la Composition API. Le système de réactivité est le même dans les deux cas. La documentation de Vue indique que le code écrit dans `<script setup>` se minifie mieux, parce que le template est compilé en une fonction placée dans la même portée et que les noms de variables locales peuvent être raccourcis, alors que le code Options API passe par des accès de propriétés sur `this`. Un projet qui n'utilise que la Composition API peut aussi désactiver l'Options API avec le flag de compilation `__VUE_OPTIONS_API__`, ce qui la retire du bundle de production. Pour la plupart des applications, ces gains restent faibles à côté de l'organisation du code.
TypeScript, performances et migration
La migration n'est pas obligatoire. Vue 3 accepte les deux API dans le même projet, et dans le même fichier si besoin. Un composant Options API peut utiliser un composable en l'appelant dans une méthode `setup()` ajoutée à côté des options existantes. Il n'y a pas besoin de réécrire des composants Options API qui fonctionnent. La migration réaliste consiste à écrire les nouveaux composants avec `<script setup>` et à ne refactoriser les anciens que lorsqu'on les modifie déjà pour une autre raison.
Quand choisir l'Options API. Des composants petits ou moyens à la logique simple. Des équipes où la plupart des développeurs apprennent Vue et profitent d'une structure explicite. Des bases de code déjà écrites en Options API qui n'ont pas besoin d'être refactorisées. Le prototypage rapide, quand nommer des refs et des composables ralentit plus que le gain d'organisation n'aide.
Quand choisir la Composition API. Des composants qui portent plusieurs préoccupations indépendantes. Toute situation où il faut partager de la logique avec état entre composants (les composables remplacent les mixins). Les projets en TypeScript. Les bibliothèques et paquets open source (les composables sont la forme de distribution attendue). Les grosses applications dont les fichiers de composants dépassent régulièrement 200 lignes.
FAQ
L'Options API est-elle dépréciée dans Vue 3 ?
Non. L'équipe de Vue maintient les deux API au même rang. L'Options API n'est pas dépréciée, sa suppression n'est pas prévue, et elle reçoit les mêmes mises à jour. La documentation présente les deux côte à côte. Choisir la Composition API est une décision d'organisation du code, pas une question de rester à jour.
Faut-il réécrire mes composants Options API avec la Composition API ?
Pas sans une raison qui dépasse l'API elle-même. Du code Options API qui fonctionne ne devient pas moins bon parce que la Composition API existe. L'approche réaliste est d'écrire les nouveaux composants avec la Composition API et de ne refactoriser les anciens que lorsqu'on les modifie déjà et que la refactorisation facilite le changement.
Quelle est la différence entre ref et reactive dans Vue 3 ?
ref() enveloppe une valeur unique et demande .value pour y accéder dans le script. reactive() enveloppe un objet dont les propriétés sont réactives sans .value. La différence pratique essentielle : reactive() perd sa réactivité quand on le déstructure ou qu'on réaffecte l'objet entier, alors que ref() n'a aucun de ces deux problèmes. La documentation de Vue et la plupart des guides de la communauté recommandent ref() par défaut.



**Les performances à l'exécution sont proches, avec deux avantages documentés pour la Composition API.** Le système de réactivité est le même dans les deux cas. La documentation de Vue indique que le code écrit dans `<script setup>` se minifie mieux, parce que le template est compilé en une fonction placée dans la même portée et que les noms de variables locales peuvent être raccourcis, alors que le code Options API passe par des accès de propriétés sur `this`. Un projet qui n'utilise que la Composition API peut aussi désactiver l'Options API avec le flag de compilation `__VUE_OPTIONS_API__`, ce qui la retire du bundle de production. Pour la plupart des applications, ces gains restent faibles à côté de l'organisation du code.