Comprendre computed dans Vue.js
Jusqu’ici, nous avons structuré notre application Vue autour de deux blocs essentiels : data() pour définir l’état – Comprendre data() dans Vue.js, et methods pour déclencher des actions – Comprendre methods dans Vue.js. Mais certains besoins ne relèvent ni d’une donnée brute, ni d’une fonction utilisateur. Ce sont des valeurs dérivées, calculées à partir d’autres, et qui doivent rester réactives. C’est là qu’intervient computed.
Plutôt que de recalculer manuellement une donnée ou de dupliquer une logique dans l’interface, on peut créer une propriété calculée. Elle se comporte comme une variable, mais Vue en surveille automatiquement les dépendances. Dès qu’une donnée utilisée dans le calcul change, la propriété est mise à jour. Sinon, elle reste mémorisée. Ce mécanisme permet d’alléger le code, de fiabiliser l’affichage, et d’optimiser les performances sans effort supplémentaire.
Dans cet article, nous allons voir ce qui distingue vraiment computed de methods, comment l’utiliser efficacement, et pourquoi il devient rapidement indispensable dès que l’interface dépend de plusieurs critères. Comme toujours, nous nous appuierons sur un cas concret issu de notre projet vidéo.
Une propriété calculée, pas une fonction appelée
À première vue, une propriété computed ressemble à une simple méthode : c’est une fonction que l’on écrit dans un objet, et qu’on appelle dans le HTML. Pourtant, sa nature est différente. On ne l’exécute pas : on l’interroge. Vue la traite comme une variable, mais qui s’auto-met à jour en fonction des données dont elle dépend.
Prenons un exemple simple. Si notre application contient un firstName et un lastName, on peut vouloir les afficher ensemble :
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}Et pour l’employer, dans l’interface il suffit d’écrire
<p>{{ fullName }}</p>Vue garde en mémoire le résultat tant que firstName ou lastName ne changent pas. Si l’un d’eux est modifié, alors — et seulement alors — fullName est recalculé. Ce comportement évite les traitements inutiles, surtout dans des interfaces complexes ou dynamiques. En clair : à chaque affichage, Vue consulte une valeur déjà prête, sans avoir besoin de relancer une fonction.
Exemple réel dans notre application vidéo : filteredVideos
Dans notre projet de gestion de vidéos musicales, l’utilisateur peut filtrer la liste affichée selon plusieurs critères : un mot saisi dans le champ de recherche, un genre sélectionné, un groupe, ou un mot-clé associé. Plutôt que de gérer ce filtrage à la main ou dans le HTML, nous avons défini une propriété computed appelée filteredVideos. C’est elle qui construit dynamiquement la liste à afficher, en tenant compte des filtres actifs.
computed: {
filteredVideos() {
const query = this.searchQuery.toLowerCase();
return this.videos.filter(video => {
const matchesSearch = query ? video.VIDEO_LABEL.toLowerCase().includes(query) : true;
const matchesGroup = this.selectedGroup ? video.GROUP_NAME === this.selectedGroup : true;
const matchesGenre = this.selectedGenre ? video.VIDEO_GENRES.includes(this.selectedGenre) : true;
const matchesKeyword = this.selectedKeyword ? video.VIDEO_KEYWORDS.includes(this.selectedKeyword) : true;
return matchesSearch && matchesGroup && matchesGenre && matchesKeyword;
});
}
}Ce calcul, assez verbeux en soi, reste isolé dans le script. Dans le HTML, on garde une syntaxe propre :
<li v-for="video in filteredVideos" :key="video.VIDEO_ID">
{{ video.VIDEO_LABEL }}
</li>Vue gère la mise à jour de filteredVideos dès qu’une des valeurs utilisées dans le calcul change. Le filtrage s’ajuste en temps réel, sans qu’on ait à recharger ou déclencher quoi que ce soit. Cette approche permet de séparer clairement la logique de traitement des données et leur affichage, tout en gardant une interface parfaitement fluide.
Pourquoi pas une méthode ?
On pourrait se dire qu’au fond, cette logique de filtrage pourrait être placée dans une méthode. Après tout, on y met bien une fonction, elle retourne un tableau filtré, et le HTML peut l’appeler. Vue l’autorise, mais le comportement n’est plus le même.
Prenons exactement le même filtre que précédemment, mais cette fois en tant que méthode :
methods: {
filterVideos() {
const query = this.searchQuery.toLowerCase();
return this.videos.filter(video => {
const matchesSearch = query ? video.VIDEO_LABEL.toLowerCase().includes(query) : true;
const matchesGroup = this.selectedGroup ? video.GROUP_NAME === this.selectedGroup : true;
const matchesGenre = this.selectedGenre ? video.VIDEO_GENRES.includes(this.selectedGenre) : true;
const matchesKeyword = this.selectedKeyword ? video.VIDEO_KEYWORDS.includes(this.selectedKeyword) : true;
return matchesSearch && matchesGroup && matchesGenre && matchesKeyword;
});
}
}Dans l’interface, on l’appelle ainsi :
<li v-for="video in filterVideos()" :key="video.VIDEO_ID">
{{ video.VIDEO_LABEL }}
</li>Mais cette fois, Vue exécute la fonction à chaque re-render de l’interface, même si rien n’a changé. Le recalcul n’est pas conditionné aux données utilisées. Plus la logique est complexe ou plus la liste est longue, plus cet impact devient visible.
Avec computed, Vue observe les dépendances et mémorise le résultat tant qu’aucune d’elles ne change. C’est un calcul optimisé. Avec methods, Vue relance la fonction à chaque fois, sans discernement. Ce n’est pas forcément problématique sur un exemple simple, mais à l’échelle d’une application, cela peut peser lourd.
Autrement dit, si vous voulez afficher une valeur calculée à partir d’autres, privilégiez computed. Si vous souhaitez déclencher une action, une soumission, ou une logique utilisateur, utilisez methods. Ce n’est pas une question de syntaxe, mais de finalité.
Attention aux dépendances implicites
Une propriété computed est censée se mettre à jour automatiquement dès qu’une donnée utilisée dans son calcul change. Mais cette mécanique repose sur un principe : Vue ne peut suivre que ce qu’elle voit passer dans le code. Si une donnée est modifiée de façon indirecte ou silencieuse, il se peut que la propriété calculée ne soit pas rafraîchie comme prévu.
Prenons un exemple concret. Supposons que nous ajoutions une nouvelle vidéo dans le tableau videos, comme ceci :
this.videos.push(newVideo);Visuellement, on attend que filteredVideos soit recalculé et que la vidéo apparaisse dans la liste. Mais ici, le tableau a été modifié en place, sans que sa référence ait changé. Or, Vue suit les références : si l’objet videos lui-même ne change pas, il peut passer à côté du changement.
Pour forcer la réactivité, on peut reconstruire le tableau :
this.videos = [...this.videos, newVideo];Ce petit détour informe Vue que la structure a été mise à jour, ce qui déclenche bien le recalcul de filteredVideos.
Même logique avec les objets ou tableaux imbriqués : si vous modifiez une propriété profondément enfouie, Vue peut ne pas capter le changement. Il ne s’agit pas d’un bug, mais d’une limite liée à l’observation des dépendances.
Cela signifie qu’en cas de comportement étrange — une liste qui ne se met pas à jour, un affichage bloqué — il faut penser à vérifier non seulement la logique du computed, mais aussi la manière dont les données sont modifiées. La réactivité de Vue est puissante, mais elle n’est pas devin : elle suit ce que vous lui montrez.
Conclusion
Avec computed, Vue nous offre un levier particulièrement élégant : celui de transformer nos données sans effort supplémentaire, tout en restant pleinement réactif. Ce n’est ni une variable à recalculer manuellement, ni une fonction appelée à chaque affichage. C’est un pont entre la logique métier et l’interface, un outil pour exposer proprement des valeurs dérivées, sans alourdir notre code.
Dans notre application vidéo, filteredVideos illustre parfaitement cet usage : on filtre une liste selon plusieurs critères, on isole la logique dans un seul bloc, et l’affichage reste fluide, quelle que soit la complexité du filtre. Cela permet de concentrer l’attention sur ce que l’on veut montrer, sans se perdre dans les conditions.
Comprendre computed, c’est franchir une étape dans la maîtrise de Vue. C’est aussi s’outiller pour concevoir des interfaces plus robustes, plus claires et plus maintenables. Dans les prochains articles, nous irons plus loin encore : écouter des changements précis avec watch, gérer des effets au montage, ou structurer nos pages avec des composants réutilisables. Chaque pièce du puzzle prend alors tout son sens.
