Qu’est-ce que Vue ?
Vue est un framework JavaScript progressif pour la création d’interfaces utilisateur. Ce terme est délibéré : vous pouvez intégrer Vue sur une seule page pour améliorer un widget spécifique, ou l’utiliser avec un outil de build pour construire une application complète. Aucune réécriture n’est nécessaire pour en tirer profit, et le framework évolue selon vos besoins.
Essentiellement, Vue repose sur deux piliers : une syntaxe de template qui étend le HTML, et un système de réactivité qui suit vos données et met à jour la vue automatiquement. Vous déclarez ce que l’UI doit afficher, et Vue s’occupe de la synchronisation.
Composants monofichier (Single-file components)
Un composant Vue réside généralement dans un fichier .vue composé de trois blocs : un template, un script et des styles. Le fait de les regrouper fait du composant une unité unique et autonome.
<!-- Card.vue -->
<script setup>
defineProps({ title: String });
</script>
<template>
<article class="card">
<h3>{{ title }}</h3>
<slot />
</article>
</template>
<style scoped>
.card {
border-radius: 1rem;
padding: 1.5rem;
}
</style>
<style scoped> limite automatiquement le CSS à ce composant, empêchant ainsi les noms de classes de “fuiter” vers l’extérieur. <script setup> est une macro de compilation qui rend la Composition API plus concise et constitue le standard moderne.
Syntaxe des templates
Les templates Vue sont du HTML enrichi d’un petit ensemble de directives. L’interpolation utilise des doubles accolades, et les directives sont des attributs préfixés par v-.
<!-- profile.vue -->
<template>
<h1>{{ user.name }}</h1>
<p v-if="user.online">Online</p>
<p v-else>Offline</p>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
<img :src="user.avatar" :alt="user.name" />
<button @click="follow">Follow</button>
</template>
Lisez les raccourcis ainsi : :src lie un attribut à une expression, et @click écoute un événement. v-if gère le rendu conditionnel, et v-for effectue des boucles avec une :key pour des mises à jour efficaces. Le template est compilé en fonctions de rendu, mais vous aurez rarement besoin de les consulter.
Réactivité : ref et reactive
Le système de réactivité de Vue surveille vos données et déclenche un nouveau rendu lorsqu’elles changent. Dans la Composition API, vous créez des valeurs réactives avec ref ou reactive.
<script setup>
import { ref, reactive } from "vue";
const count = ref(0); // .value in script
const user = reactive({ // proxy, no .value
name: "Ada",
online: true,
});
function increment() {
count.value += 1;
}
</script>
ref enveloppe n’importe quelle valeur et y accède via .value dans le script, bien que les templates le déballent automatiquement pour vous. reactive retourne un proxy profondément réactif pour un objet. Une convention courante consiste à utiliser ref systématiquement, car il fonctionne pour les primitives et est facile à réassigner.
Computed et watch
Deux fonctions permettent de gérer les valeurs dérivées et les effets de bord.
<script setup>
import { ref, computed, watch } from "vue";
const items = ref([10, 20, 30]);
const total = computed(() =>
items.value.reduce((sum, n) => sum + n, 0),
);
watch(items, (next, prev) => {
console.log("items changed", prev, next);
});
</script>
computed met son résultat en cache et ne le recalcule que lorsqu’une dépendance change — utilisez-le dès qu’une valeur est dérivée d’un autre état. watch exécute un callback lorsqu’une source change et sert aux effets de bord tels que la journalisation, la récupération de données ou la sauvegarde. Utiliser watch pour calculer une valeur est une erreur courante.
Props, emits et slots
Les données descendent via les props et remontent via les événements émis (emits).
<!-- Child.vue -->
<script setup>
const props = defineProps({
label: { type: String, required: true },
});
const emit = defineEmits(["select"]);
function handleClick() {
emit("select", props.label);
}
</script>
<template>
<button @click="handleClick">{{ label }}</button>
</template>
<!-- Parent.vue -->
<Child label="Save" @select="onSelect" />
Les props sont en lecture seule dans l’enfant, ce qui permet de maintenir la source de vérité dans le parent. Les slots permettent à un parent de passer du balisage à un enfant, l’équivalent des children de React.
Composables
Le plus grand avantage de la Composition API est la logique réutilisable. Un composable est une fonction qui utilise la réactivité et retourne un état, nommée avec un préfixe use.
// useFetch.js
import { ref, watchEffect } from "vue";
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
watchEffect(async () => {
data.value = null;
error.value = null;
try {
const res = await fetch(url.value);
data.value = await res.json();
} catch (err) {
error.value = err;
}
});
return { data, error };
}
Les composables partagent la logique, et non l’état ; ainsi, chaque composant qui appelle useFetch obtient ses propres données indépendantes. C’est l’équivalent Vue d’un hook personnalisé.
Routage et état
Vue Router gère la navigation via un mappage déclaratif entre l’URL et le composant, et Pinia est le store officiel pour l’état partagé.
// router.js
import { createRouter, createWebHistory } from "vue-router";
export const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: Home },
{ path: "/users/:id", component: UserProfile },
],
});
Utilisez un store lorsque plusieurs composants éloignés ont besoin du même état. Pour les données locales ou les échanges parent-enfant, les props et les composables sont généralement suffisants.
Bonnes pratiques
- Utilisez
script setupet la Composition API pour tout nouveau code. - Privilégiez
computedàwatchpour les valeurs dérivées. - Gardez les props en lecture seule et émettez des événements pour les modifications.
- Extrayez la logique réutilisable dans des composables.
- Utilisez des styles
scoped, ou des CSS Modules, pour garder les styles locaux. - Nommez vos composables avec un préfixe
use. - Évitez d’accéder directement à l’état d’un composant enfant ; communiquez via les props et les emits.
Erreurs courantes
- Oublier
.valuesur une ref à l’intérieur du script. - Utiliser
watchpour calculer une valeur quecomputeddevrait dériver. - Muter des props dans un composant enfant au lieu d’émettre un événement.
- Déstructurer un objet
reactiveet perdre ainsi la réactivité. - Placer tout l’état dans un store global alors qu’un état local suffirait.
- Mélanger l’Options API et la Composition API sans raison valable.
Et après ?
Vue est une excellente porte d’entrée pour découvrir les frameworks de composants et s’adapte à tous types de projets. Ajoutez Nuxt pour le rendu serveur et les conventions de routage, comparez cette approche avec React et Svelte, et continuez à perfectionner votre JavaScript. Ensuite, lancez-vous dans un petit projet — une liste filtrable ou un formulaire avec validation — et laissez la réactivité faire le travail.