Vue 3 › Conversion d'Options API vers Composition API

Suivez les 7 règles pour convertir vos composants Vue.js de l'Options API vers la Composition API pour des projets plus ambitieux, modernes et évolutifs.

Icône de calendrier MAJ en
Intermédiaire
12 chapitres

Si l’Options API est adaptée à la découverte du framework Vue.js et aux petits projets, il est de plus en plus fréquent de faire appel à Composition API pour des projets plus ambitieux. Apprenons à convertir nos composants d’Options API vers Composition API.

Options API vs Composition API : de quoi s’agit-il ?

Vue.js propose deux façons d’écrire un composant : l’Options API et la Composition API. Elles offrent les mêmes capacités, mais reposent sur des syntaxes et des logiques d’organisation différentes.

Options API

L’Options API structure le composant sous forme d’objet, découpé en sections bien définies :

  • data()
  • methods
  • computed
  • watch
  • hooks (mounted, created, etc.)

Voici un extrait de code mettant en lumière la structure des composants en Options API :

copié !
<script>
export default {
    data() {
        return {
            count: 0
        }
    },
    methods: {
        increment() {
            this.count++
        }
    },
    computed: {
        doubleCount() {
            return this.count * 2
        }
    },
    watch: {
        count() {
            console.log('Le compteur a changé')
        }
    },
    mounted() {
        console.log('Le composant est monté')
    }
}
</script>

Le code est organisé par type de logique. Cette approche est idéale pour débuter, mais devient rapidement moins lisible dès que le composant grossit ou que plusieurs fonctionnalités s’entremêlent.

Composition API

Arrivée avec Vue 3, la Composition API rassemble toute la logique du composant dans une fonction setup() ou plus généralement dans une balise <script setup>, ce qui permet de regrouper le code par fonctionnalité, et non par section (data, methods, computed, watch…).

Elle repose notamment sur :

  • ref() et reactive()
  • computed()
  • watch()
  • fonctions réutilisables (« composables »)

Voici un extrait de code mettant en lumière la structure des composants en Composition API :

copié !
<script setup>
import { ref, computed, watch, onMounted } from 'vue'

const count = ref(0)

function increment() {
    count.value++
}

const doubleCount = computed(() => count.value * 2)

watch(count, () => {
    console.log('Le compteur a changé')
})

onMounted(() => {
    console.log('Le composant est monté')
})
</script>

Cette approche est pensée pour des projets plus ambitieux, où la lisibilité, la réutilisation et l’évolutivité sont importantes.

Voici un tableau comparatif entre Options API et Composition API :

AspectOptions APIComposition API
Structure du codeOrganisé par blocs (data, methods…) au sein d’un objet de configuration uniqueRegroupé par fonctionnalité dans setup
LisibilitéSimple au débutPlus claire sur des composants complexes
RéutilisationLimitéeExcellente (composables)
Taille de projet viséePetits / moyensMoyens / gros
TypeScriptMoins naturelIntégration fluide
Organisation logiqueÉclatée par type (data/methods/computed)Regroupée par fonctionnalité

Convertir ses composants Options API vers Composition API

1. La balise script

Le code d’un composant respectant la Composition API doit être contenu dans des balises <script setup>.

Options API :

copié !
<script>
// Mon composant en Options API
</script>

Composition API :

copié !
<script setup>
// Mon composant en Composition API
</script>

2. Les données réactives

Concernant le state de notre application Vue, il va falloir remplacer les objets retournés par data() par l’usage des fonctions ref() ou reactive().

Options API :

copié !
<script>
export default {
    data() {
        return {
            count: 0
        }
    }
}
</script>

<template>
	<p>Compteur : {{ count }}</p>
</template>

Composition API :

copié !
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
	<p>Compteur : {{ count }}</p>
</template>
Quelle est la différence entre ref et reactive ? 🤔

La fonction ref() est à privilégier pour les données simples (comme un compteur), tandis que reactive() est plus adapté pour les objets complexes.

Utilisation de ref pour une variable simple :

copié !
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

Utilisation de reactive pour un objet complexe :

copié !
<script setup>
import { reactive } from 'vue'

const user = reactive({
    pseudo: 'Athios',
    age: 30
})
</script>

3. Les méthodes

Du côté des méthodes, la propriété methods n’est plus nécessaire. Les méthodes peuvent être directement définies dans le script.

Options API :

copié !
<script>
export default {
    data() {
        return {
            count: 0
        }
    },
    methods: {
        increment() {
            this.count++
        }
    }
}
</script>

<template>
	<p>Compteur : {{ count }}</p>
	<button @click="increment">Incrémenter</button>
</template>

Composition API :

copié !
<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
    count.value++
}
</script>

<template>
	<p>Compteur : {{ count }}</p>
	<button @click="increment">Incrémenter</button>
</template>

Une remarque importante est que this n’est plus disponible dans ce contexte, et il se voit remplacé par .value.

4. Les computed

Les propriétés calculées (« computed ») ne sont plus déclarées dans une propriété computed mais bien au sein d’une constante stockant le retour d’une fonction computed(), qui elle-même prend en paramètre une fonction retournant le « calcul ».

Options API :

copié !
<script>
export default {
    data() {
        return {
            firstName: 'Ada',
            lastName: 'Lovelace'
        }
    },
    computed: {
        fullName() {
            return `${this.firstName} ${this.lastName}`
        }
    }
}
</script>

<template>
    <p>{{ fullName }}</p>
</template>

Composition API :

copié !
<script setup>
import { ref, computed } from 'vue'

const firstName = ref('Ada')
const lastName = ref('Lovelace')

const fullName = computed(() => `${firstName.value} ${lastName.value}`)
</script>

<template>
    <p>{{ fullName }}</p>
</template>

5. Les watchers

Les observateurs (« watchers ») Vue vont pour leur part abandonner l’usage de la propriété watch, qui se verra remplacée par une constante stockant le retour d’une fonction watch(), qui elle-même prend en paramètre :

  • La variable réactive à observer.
  • La fonction à exécuter lorsqu’elle change.

Options API :

copié !
<script>
export default {
    data() {
        return {
            firstName: 'Ada'
        }
    },
    watch: {
        firstName(newValue, oldValue) {
            console.log(`Le prénom a été modifié de ${oldValue} à ${newValue}`)
        }
    }
}
</script>

<template>
    <p>{{ firstName }}</p>
</template>

Composition API :

copié !
<script setup>
import { ref, watch } from 'vue'

const firstName = ref('Ada')

watch(firstName, (newValue, oldValue) => {
    console.log(`Le prénom a été modifié de ${oldValue} à ${newValue}`)
})
</script>

<template>
    <p>{{ firstName }}</p>
</template>

6. Hooks de cycle de vie des composants

Anciennement on exploitait les hooks de cycle de vie des composants via les propriétés mounted, created, updated, etc.

Avec la Composition API, les hooks de cycle de vie des composants sont disponibles via des fonctions à la forme on<lifecycle>.

Options API :

copié !
<script>
export default {
    mounted() {
        console.log('Le composant est monté')
    }
}
</script>

Composition API :

copié !
<script setup>
import { onMounted } from 'vue'

onMounted(() => {
    console.log('Le composant est monté')
})
</script>

7. Imports explicites

Comme vous l’avez remarqué dans les exemples précédents, Composition API ne permet plus d’exporter un unique objet contenant toutes les fonctions réactives et les hooks dont on a besoin.

Il est maintenant nécessaire d’importer explicitement ces éléments : ref, reactive, computed, watch, onMounted, etc.

copié !
<script setup>
import { ref, reactive, computed, watch, onMounted... } from 'vue'
</script>

Composition API n’a désormais plus de secret pour vous ! Vous êtes capables de transformer vos composants Options API en composants Composition API, pour des projets plus ambitieux, modernes et évolutifs.