Données réactives
La réactivité est le concept le plus fondamental de Vue3.
Dans ce chapitre, vous comprendrez ce qu'est la réactivité et apprendrez à utiliserrefetreactivepour gérer les données et implémenter la fonctionnalité de filtrage par catégorie.
Qu'est-ce que la réactivité ?
La réactivité signifie :Lorsque les données changent, la page se met à jour automatiquement.。
L'approche JS traditionnelle est la suivante : après avoir modifié une variable, vous devez mettre à jour le DOM manuellement.
Le système réactif de Vue3 suit automatiquement les changements de données et notifie la vue pour qu'elle se rafraîchisse—vous n'avez qu'à vous soucier des données, pas du DOM.
Exemple
import { ref } from 'vue'
// Les variables encapsulées par ref sont réactives
const count = ref(0)
// Après modification de count, {{ count }} dans le template se met à jour automatiquement
function increment() {
count.value++ // Remarque : en JS, vous devez utiliser .value pour accéder à la valeur
}
</script>
<template>
<p>Nombre de clics : {{ count }}</p>
<!-- Déballage automatique dans le template, pas besoin de .value -->
<button @click="increment">+1</button>
</template>
Après avoir cliqué sur le bouton, le nombre affiché sur la page change automatiquement — c'est la réactivité.
Vous n'avez pas besoin d'écrire quoi que ce soitdocument.querySelectorouinnerHTMLpour mettre à jour la page.
ref — Gestion des types primitifs
refest l'API réactive la plus couramment utilisée dans Vue3, adaptée pour encapsuler des données de type primitif.
Les types primitifs incluent : chaînes de caractères, nombres, booléens, null, undefined.
Syntaxe
Exemple
import { ref } from 'vue'
// Création d'une ref
const name = ref('EXAMPLE') // Chaîne
const age = ref(18) // Nombre
const isVip = ref(false) // Booléen
// Lecture de .value
console.log(name.value) // "EXAMPLE"
console.log(age.value) // 18
// Modification de .value
name.value = 'Hello EXAMPLE'
age.value++
isVip.value = !isVip.value
</script>
<template>
<p>Nom : {{ name }}</p>
<!-- Dans les templates, ref est automatiquement déballé, aucun .value nécessaire -->
<p>Âge : {{ age }}</p>
<p>VIP : {{ isVip }}</p>
</template>
La chose la plus importante à retenir :Dans le code JS, vous avez besoin de .value, mais pas dans les templates.C'est l'erreur la plus courante que commettent les débutants.
reactive — Gestion des objets et des tableaux
reactiveConvient pour envelopper des données de type référence telles que des objets ou des tableaux.
Contrairement à ref, reactive n'a pas besoin de.value.value, et vous pouvez accéder directement aux propriétés.
Exemple
import { reactive } from 'vue'
// Envelopper un objet avec reactive
const user = reactive({
name: 'Xiaoming',
age: 20,
hobbies: ['programming', 'running']
})
// Accès et modification directs, pas besoin de .value
console.log(user.name) // "Xiao Ming"
user.name = 'Xiao Hua' // Mise à jour réactive
user.hobbies.push('reading') // Les opérations sur les tableaux sont aussi réactives
</script>
<template>
<p>Nom : {{ user.name }}</p>
<p>Âge : {{ user.age }}</p>
<ul>
<li v-for="(hobby, index) in user.hobbies" :key="index">
{{ hobby }}
</li>
</ul>
</template>
Deux limitations de reactive
| Limite | Description | Solution |
|---|---|---|
| Ne peut encapsuler que les types objet | Impossible de passer des types primitifs comme des chaînes de caractères, des nombres | Utilisez ref pour les types primitifs |
| Ne peut pas être remplacé dans son ensemble | Impossible d'affecter l'objet entier à un nouvel objet | Utilisez Object.assign() ou passez à ref |
Exemple
// Erreur : impossible de remplacer l'objet réactif dans son ensemble
const state = reactive({ count: 0 })
// state = { count: 1 } // Cela ne fonctionnera pas, la réactivité sera perdue
// Approche correcte 1 : modifier les propriétés au lieu de remplacer l'ensemble
state.count = 1
// Approche correcte 2 : utiliser ref pour envelopper l'objet (ref permet de remplacer l'ensemble)
const stateRef = ref({ count: 0 })
stateRef.value = { count: 1 } // Ça fonctionne ! Parce que la .value de ref peut être remplacée
ref vs reactive : quand utiliser lequel
| Scénario | Recommandation | Exemple |
|---|---|---|
| Une seule chaîne/nombre/booléen | ref | const name = ref('小明') |
| Un seul tableau | ref | const list = ref([]) |
| Un seul objet | ref et reactive fonctionnent tous les deux | const user = ref({}) |
| Plusieurs états sans rapport | Utiliser ref pour chaque | Un ref par ligne |
| Un groupe d’états fortement liés | reactive | p. ex., données de formulaire, collection de configuration |
La pratique la plus courante en développement réel est :Toujours utiliser ref, y compris pour les objets et les tableaux。
Cela permet de garder un style de code cohérent, et vous n’avez pas besoin de changer de modèle mental entre ref et reactive.
Les chapitres suivants de ce tutoriel utilisent uniformément ref pour gérer tout l’état. Lorsque vous rencontrerez des endroits qui nécessitent
.valuereactive, ces endroits seront spécialement signalés.
computed — Propriétés calculées
computedest « des données calculées à partir de données existantes. »
Il possède deux caractéristiques principales :La mise en cache——lorsque les dépendances ne changent pas, il ne se recalcule pas ;Le suivi automatique——lorsque les dépendances changent, il se met à jour automatiquement.
Exemple
import { ref, computed } from 'vue'
const articles = ref([
Premiers pas avec Vue3
{ id: 2, title: 'Explication détaillée des promesses', category: 'JavaScript' },
Disposition en grille
{ id: 4, title: 'Composition API', category: 'Vue' }
])
const activeCategory = ref('Toutes')
// computed filtre les articles en fonction d'activeCategory
const filteredArticles = computed(() => {
if (activeCategory.value === 'Toutes') {
return articles.value
}
return articles.value.filter(a => a.category === activeCategory.value)
})
// computed peut aussi être utilisé pour les statistiques
const totalCount = computed(() => articles.value.length)
const filteredCount = computed(() => filteredArticles.value.length)
</script>
<template>
<p>Total {{ totalCount }} articles, actuellement affichés : {{ filteredCount }}</p>
<!-- Boutons de catégorie -->
<button @click=activeCategory = 'All'>Tous</button>
<button @click="activeCategory = 'Vue'">Vue</button>
<button @click="activeCategory = 'JavaScript'">JavaScript</button>
<button @click="activeCategory = 'CSS'">CSS</button>
<!-- Liste des articles filtrés -->
<div v-for="article in filteredArticles" :key="article.id">
<h3>{{ article.title }}</h3>
<span>{{ article.category }}</span>
</div>
</template>
Chaque fois queactiveCategorymodifications,filteredArticlesil recalculera automatiquement, et la page s'actualise automatiquement.
Remarque : computed renvoie une ref, donc pour y accéder en JS, il faut aussi
.value.value. Cependant, dans l'exemple ci-dessus, nous l'avons utilisé directement dans le template, où il est automatiquement déballé.
Exercice pratique : ajouter un filtrage par catégorie au blog
Appliquez computed à la page d'accueil du blog pour filtrer les articles en cliquant sur les boutons de catégorie.
Exemple
import { ref, computed } from 'vue'
const articles = ref([
{ id: 1, title: 'Vue3 : guide complet pour débuter', summary: 'Apprendre Vue3 à partir de zéro', category: 'Vue', date: '2024-05-10' },
{ id: 2, title: 'La programmation asynchrone en JS en détail', summary: Comprendre Promise et async/await, category: 'JavaScript', date: '2024-05-08' },
{ id: 3, title: 'Mise en page pratique avec CSS Grid', summary: 'Implémenter une mise en page responsive avec Grid', category: 'CSS', date: '2024-05-05' },
{ id: 4, title: 'Principes de réactivité de Vue3', summary: 'Compréhension approfondie de ref et reactive', category: 'Vue', date: '2024-05-03' },
{ id: 5, title: 'Guide complet de Flexbox', summary: 'Apprendre la mise en page flex en un seul article', category: 'CSS', date: '2024-05-01' },
])
// Toutes les catégories (dédoublonnées)
const categories = computed(() => {
const cats = articles.value.map(a => a.category)
return ['All', ...new Set(cats)] // Ajouter 'All' au début
})
// Catégorie actuellement sélectionnée
const activeCategory = ref('Toutes')
// Filtrer les articles par catégorie
const filteredArticles = computed(() => {
if (activeCategory.value === 'Toutes') {
return articles.value
}
return articles.value.filter(a => a.category === activeCategory.value)
})
</script>
<template>
<div class="home">
<h2>Derniers articles</h2>
<!-- Boutons de filtre par catégorie -->
<div class="category-bar">
<button
v-for="cat in categories"
:key="cat"
:class="{ active: activeCategory === cat }"
@click="activeCategory = cat"
>
{{ cat }}
</button>
</div>
<!-- Nombre de résultats filtrés -->
<p class="result-info">Total {{ filteredArticles.length }} articles</p>
<!-- Liste des articles -->
<div class="article-grid">
<div v-for="article in filteredArticles" :key="article.id" class="card">
<span class="tag">{{ article.category }}</span>
<h3>{{ article.title }}</h3>
<p>{{ article.summary }}</p>
<span class="date">{{ article.date }}</span>
</div>
</div>
</div>
</template>
<style scoped>
.category-bar {
display: flex;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.category-bar button {
padding: 6px 16px;
border: 1px solid #ddd;
border-radius: 20px;
background: #fff;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.category-bar button.active {
background: #427DB8;
color: #fff;
border-color: #427DB8;
}
.category-bar button:hover {
border-color: #427DB8;
}
.result-info {
color: #999;
font-size: 14px;
margin-bottom: 16px;
}
</style>
Désormais, lorsque vous cliquez sur différents boutons de catégorie, la liste d’articles est filtrée en temps réel. Vous n’avez pas besoin d’écrire de code de manipulation du DOM ; il vous suffit de vous concentrer sur la logique des changements de données.
Résumé du chapitre
Dans ce chapitre, vous avez maîtrisé les trois API principales du système de réactivité de Vue 3 : ref encapsule les types primitifs (utiliser .value en JS), reactive encapsule les objets, et computed dérive des données calculées.
Grâce à computed + les boutons de filtrage par catégorie, vous avez découvert le modèle de développement des « vues pilotées par les données » — modifiez les données, la page se met à jour automatiquement.
Autres extensions