Nous poursuivons avec le Chapitre 3 de la formation Vue.js, incluant les notions théoriques, les exemples de code, et le résultat final de l’atelier fil rouge : la gestion d’un tableau de tâches avec ref() et l’affichage du nombre de tâches terminées via un computed().
Chapitre 3 : Réactivité et gestion d’état
L’objectif est d’apprendre à gérer des données dynamiques avec ref() et reactive(), à utiliser computed() pour dériver des valeurs, et à afficher une liste de tâches avec v-for.
Notions à apprendre
1. ref() vs reactive()
ref(): pour les valeurs primitives (string, number, boolean) ou objets simples. Accès via.valuereactive(): pour les objets complexes. Pas besoin de.value(mais attention aux problèmes de réactivité lors de la réaffectation)
Recommandé : Utiliser ref() pour les tableaux et objets simples, surtout en <script setup>.
2. computed()
- Crée une valeur dérivée, recalculée uniquement si ses dépendances changent
- Très utile pour les filtres, totaux, statistiques
3. v-for pour boucler sur une liste
- Syntaxe :
v-for="item in list" :key="item.id" - Toujours utiliser
:keypour une performance optimale et éviter les bugs de rendu
4. Mutation vs réactivité
- Vue détecte les mutations sur les tableaux/objets via
push(),splice(),item.property = value - Éviter :
array = newArray→ cela casse la réactivité. Utiliserarray.splice(0, array.length, ...newArray)ouref().value = newArray
Exemple de code : Gestion d’un tableau de tâches
<!-- src/App.vue (version simplifiée pour l’exemple) -->
<template>
<div class="app">
<h1>Mes tâches</h1>
<div class="stats">
<p>Total : {{ tasks.length }}</p>
<p>Terminées : {{ doneTasks.length }}</p>
</div>
<ul class="task-list">
<li v-for="task in tasks" :key="task.id" class="task-item">
{{ task.title }} — <span :class="task.status">{{ task.status }}</span>
</li>
</ul>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
// Tableau de tâches réactif
const tasks = ref([
{ id: 1, title: 'Apprendre Vue.js', status: 'done' },
{ id: 2, title: 'Créer un composant', status: 'todo' },
{ id: 3, title: 'Gérer l’état', status: 'inprogress' }
])
// Computed : liste des tâches terminées
const doneTasks = computed(() => {
return tasks.value.filter(task => task.status === 'done')
})
</script>
<style scoped>
.app {
padding: 2rem;
max-width: 600px;
margin: 0 auto;
}
.stats {
background: #f0f0f0;
padding: 1rem;
border-radius: 8px;
margin-bottom: 1rem;
display: flex;
gap: 1rem;
justify-content: space-between;
}
.task-list {
list-style: none;
padding: 0;
}
.task-item {
background: #fff;
border: 1px solid #ddd;
padding: 0.75rem;
margin: 0.5rem 0;
border-radius: 6px;
display: flex;
justify-content: space-between;
align-items: center;
}
.task-item .done {
color: #2ecc71;
font-weight: bold;
}
.task-item .todo {
color: #e74c3c;
}
.task-item .inprogress {
color: #f39c12;
}
</style>
Atelier fil rouge : Afficher le nombre de tâches terminées
Objectif :
- Déclarer un tableau de tâches dans
App.vueavecref() - Créer un
computed()qui filtre les tâches avecstatus === 'done' - Afficher le nombre total de tâches et le nombre de tâches terminées
- Afficher la liste des tâches avec leur statut
Résultat final : App.vue mis à jour
<!-- src/App.vue -->
<template>
<div class="app">
<header>
<h1>Mon gestionnaire de tâches</h1>
<p>Chapitre 3 : Réactivité et gestion d’état</p>
</header>
<main>
<div class="stats">
<p><strong>Total :</strong> {{ tasks.length }}</p>
<p><strong>Terminées :</strong> {{ doneTasks.length }}</p>
</div>
<div class="task-list">
<TaskCard
v-for="task in tasks"
:key="task.id"
:title="task.title"
:description="task.description"
:status="task.status"
/>
</div>
</main>
<footer>
<p>Vue.js — Formation Chapitre 3</p>
</footer>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import TaskCard from './components/TaskCard.vue'
// Tableau de tâches réactif
const tasks = ref([
{ id: 1, title: 'Créer le composant TaskCard', description: 'Chapitre 2', status: 'done' },
{ id: 2, title: 'Gérer l’état avec ref()', description: 'Chapitre 3', status: 'todo' },
{ id: 3, title: 'Utiliser computed()', description: 'Chapitre 3', status: 'inprogress' }
])
// Computed : tâches terminées
const doneTasks = computed(() => {
return tasks.value.filter(task => task.status === 'done')
})
</script>
<style scoped>
.app {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 2rem auto;
padding: 2rem;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
header h1 {
color: #42b983;
margin-bottom: 0.5rem;
}
header p {
color: #666;
font-size: 0.9rem;
}
.stats {
background: #f0f0f0;
padding: 1rem;
border-radius: 8px;
margin-bottom: 1rem;
display: flex;
gap: 1rem;
justify-content: space-between;
}
.task-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
footer {
margin-top: 2rem;
text-align: center;
font-size: 0.8rem;
color: #999;
}
</style>
Explication du résultat
- Le tableau
tasksest déclaré avecref()→ il est réactif. doneTasksest uncomputed()→ il se met à jour automatiquement sitaskschange.- Les tâches sont affichées avec
v-for→ chaqueTaskCardreçoit ses props (title,description,status). - Le composant
TaskCardest mis à jour pour afficher le statut (voir ci-dessous).
Mise à jour de TaskCard.vue (pour afficher le statut)
<!-- src/components/TaskCard.vue -->
<template>
<div class="task-card" :class="status">
<h3 class="task-title">{{ title }}</h3>
<p class="task-description">{{ description }}</p>
<span class="status-badge">{{ status }}</span>
</div>
</template>
<script setup>
defineProps({
title: {
type: String,
required: true
},
description: {
type: String,
default: 'Aucune description'
},
status: {
type: String,
default: 'todo',
validator: (value) => ['todo', 'inprogress', 'done'].includes(value)
}
})
</script>
<style scoped>
.task-card {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
margin: 0.5rem 0;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
transition: transform 0.2s;
position: relative;
}
.task-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.task-title {
margin: 0 0 0.5rem 0;
color: #333;
font-size: 1.1rem;
}
.task-description {
margin: 0;
color: #666;
font-size: 0.9rem;
line-height: 1.4;
}
.status-badge {
position: absolute;
top: 0.5rem;
right: 0.5rem;
padding: 0.25rem 0.5rem;
border-radius: 12px;
font-size: 0.75rem;
font-weight: bold;
color: white;
}
.task-card.todo .status-badge {
background: #e74c3c;
}
.task-card.inprogress .status-badge {
background: #f39c12;
}
.task-card.done .status-badge {
background: #2ecc71;
}
</style>
Testez-le vous-même !
- Mettez à jour
TaskCard.vueavec le code ci-dessus (ajout du statut). - Mettez à jour
App.vueavec le code du résultat final. - Lancez le serveur :
npm run dev
- Ouvrez
http://localhost:5173→ vous voyez :
- Le nombre total et terminé de tâches
- 3 cartes de tâches avec statut coloré
Prochain chapitre
Dans le chapitre 4, nous aborderons la gestion des événements et les formulaires : vous apprendrez à créer un formulaire pour ajouter une nouvelle tâche, avec validation et gestion des événements.
Tu as maintenant une liste de tâches dynamique, avec un compteur de tâches terminées, et un composant TaskCard qui affiche le statut. C’est la base de toute application de gestion de tâches !

J’avais envie de me replonger dans les concepts du Management d’entreprise, du Marketing et de la Gestion des Ressources Humaines. En effet, après plusieurs années ou j’ai suivis des formations et je me suis auto-formé aux Technologies de l’information et au Développement d’applications informatique je souhaitais revenir à mes premiers centre d’intérêts. Dans mon cursus scolaire, j’aimais les sciences économiques et la gestion d’entreprise. C’est une manière de lier ces deux passions.