blog

Vue 3 : les nouveautés

Tarik
3 min de lecture

Il y a les notes de version, et il y a le ressenti réel en développement. En passant de Vue 2 à Vue 3 sur une application concrète, voici ce qui m’a sauté aux yeux. Pas de comparatif exhaustif ici, juste ce qui compte pour coder.


Composition API : un autre paradigme

Le changement le plus visible (et structurant), c’est la Composition API.

L’approche setup() centralise les logiques au lieu de les disperser dans data, methods, computed et compagnie. On gagne en lisibilité sur des composants complexes, surtout quand plusieurs blocs de logique doivent interagir.

Avant (Vue 2) :

export default {
data() { return { count: 0 }; },
methods: {
increment() { this.count++ }
}
}

Après (Vue 3) :

export default {
setup() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
}

Au début, c’est plus verbeux. Mais sur le moyen terme, ça clarifie tout. Et surtout, on peut extraire ses logiques dans des fonctions réutilisables.


La réactivité avec ref et reactive

Autre changement fondamental : fini les objets magiques dans data. Avec Vue 3, on utilise ref() pour les primitives et reactive() pour les objets. Et on manipule .value.

C’est plus explicite, mais aussi plus rigide. Il faut oublier les raccourcis de Vue 2.


Les watch et computed gagnent en souplesse

watch accepte désormais des fonctions directement, ce qui évite les chaînes de caractères ou les bizarreries de dépendance implicite.

watch(() => props.id, (newId) => {
// logique
})

computed fonctionne à peu près pareil mais est devenu encore plus puissant avec la possibilité de le rendre writable.


Data flow : plus clair, plus contrôlé, plus explicite

Le flux de données dans Vue 3 est devenu plus strict, mais aussi plus lisible et prévisible.

  • Les props sont inchangées dans leur usage, mais leur typage est mieux pris en charge, notamment avec defineProps() dans les <script setup>.
  • Les événements émis doivent être déclarés avec defineEmits() (ou emits: []), ce qui renforce la clarté du contrat d’un composant : on sait ce qu’il accepte et ce qu’il renvoie.
const emit = defineEmits(['submit'])
emit('submit', formData)

Fini les magies silencieuses de $listeners, $attrs, $scopedSlots : tout est maintenant explicite. Si on veut transmettre des props ou des events, on le fait à la main avec v-bind="attrs" ou via les objets fournis.

Les attrs et slots sont accessibles via useAttrs() et useSlots() dans un setup(), ce qui permet un meilleur contrôle sur ce qu’on laisse passer au composant enfant.


Plus besoin de Vue.extend, et defineComponent devient la norme

Avec TypeScript, defineComponent() est une bénédiction. Même sans TS, ça structure mieux. Mais ça rajoute une couche à digérer pour ceux qui codent à l’instinct.


Global API changée : attention aux plugins

Plus de Vue.use(), on passe par app.use() dans un fichier dédié :

const app = createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')

C’est plus logique, surtout pour les SSR/Nuxt-like, mais ça demande une adaptation pour les anciens plugins non mis à jour.


Conclusion : plus rigide, mais plus propre

Vue 3 impose une discipline. Au début, on comprends rien, on se dit que c’est du React. Puis on comprend que ça pousse à écrire du code modulaire, testable, maintenable.

C’est une refonte en profondeur : ce n’est pas juste une version « améliorée », c’est une nouvelle façon de penser ses composants.

Si tu as besoin d’un dev Vue pour coder ton application :

je travaille

Basé à Avignon, je travaille en présentiel dans le triangle Avignon/Marseille/Montpellier et en remote partout en France.

Travail en présentiel

Avignon (base principale)
Marseille (1h de route)
Montpellier (1h30 de route)

Travail à distance

Disponible en remote partout en France et en Europe. Avec outils de collaboration modernes pour un travail efficace à distance.

Zoom Teams Slack GitHub

Contact rapide

Je réponds généralement dans les 24h. Pour les urgences, n'hésitez pas à m'appeler directement.