La réactivité
Ce que tu vas apprendre
- Déclarer un état réactif avec
ref()etreactive(). - Calculer une valeur à partir d'autres avec
computed(). - Lier un champ de formulaire à une variable avec
v-model.
L'état réactif avec ref
Une variable JavaScript normale ne prévient pas Vue quand elle change. Pour que l'affichage suive, tu la déclares avec ref().
<script setup>
import { ref } from 'vue'
const portions = ref(4)
function ajouter() {
portions.value++
}
</script>
<template>
<button @click="ajouter">{{ portions }} portions</button>
</template>
ref() enveloppe la valeur dans un objet qui a une propriété .value. Dans le script, tu lis et modifies portions.value. Dans le template, Vue déballe automatiquement le ref : tu écris {{ portions }}, sans .value.
La documentation présente ref() comme l'API principale pour déclarer un état.
L'état d'un objet avec reactive
reactive() rend réactif un objet entier, sans passer par .value.
<script setup>
import { reactive } from 'vue'
const recette = reactive({ nom: 'Crêpes', minutes: 20 })
function allonger() {
recette.minutes += 5
}
</script>
<template>
<p>{{ recette.nom }} : {{ recette.minutes }} min</p>
<button @click="allonger">+ 5 min</button>
</template>
Mais reactive() a des limites :
- Il ne fonctionne que sur les objets, tableaux,
MapetSet, pas sur un nombre ou un texte. - Tu ne peux pas remplacer l'objet entier (
recette = {...}) : la réactivité serait perdue. - Si tu extrais une propriété dans une variable (
const { minutes } = recette), elle n'est plus réactive.
C'est pourquoi ref() est le choix par défaut, même pour un objet : const recette = ref({ ... }).
ref(). Tu écris .value dans le script, mais tu évites les pièges de reactive().Les valeurs calculées : computed
Une propriété calculée est une valeur qui se déduit d'autres valeurs réactives. Tu la déclares avec computed().
<script setup>
import { ref, computed } from 'vue'
const prixParPortion = ref(2.5)
const portions = ref(4)
const total = computed(() => prixParPortion.value * portions.value)
</script>
<template>
<p>Coût total : {{ total }} €</p>
</template>
Dès que prixParPortion ou portions change, total est recalculé. Dans le script, on lit un computed avec .value aussi (total.value).
Computed ou fonction ?
Une fonction appelée dans le template donnerait le même résultat. La différence tient au cache.
| Propriété calculée | Fonction | |
|---|---|---|
| Recalcul | Seulement quand une dépendance change. | À chaque nouvel affichage du composant. |
| Écriture | En lecture seule. | Libre. |
Une propriété calculée est en lecture seule : lui assigner une valeur déclenche un avertissement en console. Elle sert à calculer, jamais à modifier un état.
Date.now(), n'est pas suivie : un computed qui en dépend ne se mettra jamais à jour.Lier un champ : v-model
v-model relie un champ de formulaire à une variable, dans les deux sens. Ce que tape l'utilisateur met à jour la variable, et inversement.
<script setup>
import { ref, computed } from 'vue'
const recherche = ref('')
const toutes = ['Tarte aux pommes', 'Crêpes', 'Soupe à l\'oignon']
const resultats = computed(() =>
toutes.filter((nom) => nom.toLowerCase().includes(recherche.value.toLowerCase()))
)
</script>
<template>
<input v-model.trim="recherche" placeholder="Chercher une recette" />
<p v-for="nom in resultats" :key="nom">{{ nom }}</p>
</template>
Le modificateur .trim retire les espaces au début et à la fin de ce que tape l'utilisateur.
Remarque l'enchaînement : v-model alimente un ref, et un computed en tire la liste filtrée. C'est le schéma le plus courant dans une application Vue.
À retenir
ref()déclare un état réactif :.valuedans le script, rien dans le template.reactive()convient aux objets, mais perd la réactivité si tu le remplaces ou l'extrais.computed()calcule une valeur dérivée, mise en cache et en lecture seule.v-modelrelie un champ à une variable dans les deux sens ;.trimnettoie les espaces.- Un état se déclare une fois, et tout ce qui s'en déduit passe par
computed().
Pour aller plus loin
Sources officielles
Ensuite
Le template et les directives
Afficher des données avec l'interpolation, lier des attributs avec v-bind, réagir aux clics avec v-on, puis afficher selon une condition ou une liste.
Props, événements et v-model sur un composant
Faire communiquer un composant parent et son enfant avec defineProps, defineEmits et defineModel.
- Projet
- Lignes de code
- Niveau
- 4e étage
- Appartement
- Vue
- Pièce
- 3/7
- Plan n°
- vue/03.reactivite