[Medium] ref vs reactive
1. What are ref and reactive?
Qu'est-ce que ref et reactive ?
ref et reactive sont deux API fondamentales de la Composition API de Vue 3 pour créer des données réactives.
ref
Définition : ref sert à créer une valeur de type primitif ou une référence d'objet réactive.
Cliquez pour voir l'exemple de base de ref
<script setup>
import { ref } from 'vue';
// Types primitifs
const count = ref(0);
const message = ref('Hello');
const isActive = ref(true);
// Objet (on peut aussi utiliser ref)
const user = ref({
name: 'John',
age: 30,
});
// L'accès nécessite .value
console.log(count.value); // 0
count.value++; // Modifier la valeur
</script>
reactive
Définition : reactive sert à créer un objet réactif (ne peut pas être utilisé directement pour les types primitifs).
Cliquez pour voir l'exemple de base de reactive
<script setup>
import { reactive } from 'vue';
// Uniquement pour les objets
const state = reactive({
count: 0,
message: 'Hello',
user: {
name: 'John',
age: 30,
},
});
// Accès direct aux propriétés, pas besoin de .value
console.log(state.count); // 0
state.count++; // Modifier la valeur
</script>
2. ref vs reactive: Key Differences
Principales différences entre ref et reactive
1. Types applicables
ref : Peut être utilisé pour tout type
const count = ref(0); // Nombre
const message = ref('Hello'); // Chaîne
const isActive = ref(true); // Booléen
const user = ref({ name: 'John' }); // Objet
const items = ref([1, 2, 3]); // Tableau
reactive : Uniquement pour les objets
const state = reactive({ count: 0 }); // Objet
const state = reactive([1, 2, 3]); // Tableau (c'est aussi un objet)
const count = reactive(0); // Erreur : type primitif non supporté
const message = reactive('Hello'); // Erreur : type primitif non supporté
2. Mode d'accès
ref : Nécessite .value pour accéder
Cliquez pour voir l'exemple d'accès ref
<script setup>
import { ref } from 'vue';
const count = ref(0);
// En JavaScript, .value est nécessaire
console.log(count.value); // 0
count.value = 10;
// Dans le template, déballage automatique, pas besoin de .value
</script>
<template>
<div>{{ count }}</div>
<!-- Déballage automatique, pas besoin de .value -->
</template>
reactive : Accès direct aux propriétés
Cliquez pour voir l'exemple d'accès reactive
<script setup>
import { reactive } from 'vue';
const state = reactive({ count: 0 });
// Accès direct aux propriétés
console.log(state.count); // 0
state.count = 10;
</script>
<template>
<div>{{ state.count }}</div>
</template>
3. Réaffectation
ref : Peut être réaffecté
const user = ref({ name: 'John' });
user.value = { name: 'Jane' }; // Réaffectation possible
reactive : Ne peut pas être réaffecté (perd la réactivité)
let state = reactive({ count: 0 });
state = { count: 10 }; // Perd la réactivité, ne déclenchera pas de mise à jour
4. Déstructuration
ref : La déstructuration conserve la réactivité
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value; // Déstructuration de valeurs primitives, perd la réactivité
// Mais on peut déstructurer les ref eux-mêmes
const nameRef = ref('John');
const ageRef = ref(30);
reactive : La déstructuration perd la réactivité
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state; // Perd la réactivité
// Il faut utiliser toRefs pour conserver la réactivité
import { toRefs } from 'vue';
const { count, message } = toRefs(state); // Conserve la réactivité
3. When to Use ref vs reactive?
Quand utiliser ref ? Quand utiliser reactive ?
Situations pour utiliser ref
-
Valeurs de types primitifs
const count = ref(0);const message = ref('Hello'); -
Objets nécessitant une réaffectation
const user = ref({ name: 'John' });user.value = { name: 'Jane' }; // Réaffectation possible -
Références de template (Template Refs)
<template><div ref="container"></div></template><script setup>const container = ref(null);</script> -
Situations nécessitant la déstructuration
const state = ref({ count: 0, message: 'Hello' });// La déstructuration de valeurs primitives fonctionne
Situations pour utiliser reactive
-
États d'objets complexes
const formState = reactive({username: '',password: '',errors: {},}); -
États ne nécessitant pas de réaffectation
const config = reactive({apiUrl: 'https://api.example.com',timeout: 5000,}); -
Plusieurs propriétés associées regroupées
const userState = reactive({user: null,loading: false,error: null,});
4. Common Interview Questions
Questions d'entretien courantes
Question 1 : Différences de base
Expliquez les différences et les résultats du code suivant.
// Cas 1 : Utilisation de ref
const count1 = ref(0);
count1.value = 10;
console.log(count1.value); // ?
// Cas 2 : Utilisation de reactive
const state = reactive({ count: 0 });
state.count = 10;
console.log(state.count); // ?
// Cas 3 : Réaffectation de reactive
let state2 = reactive({ count: 0 });
state2 = { count: 10 };
console.log(state2.count); // ?
Cliquez pour voir la réponse
// Cas 1 : Utilisation de ref
const count1 = ref(0);
count1.value = 10;
console.log(count1.value); // 10
// Cas 2 : Utilisation de reactive
const state = reactive({ count: 0 });
state.count = 10;
console.log(state.count); // 10
// Cas 3 : Réaffectation de reactive
let state2 = reactive({ count: 0 });
state2 = { count: 10 }; // Perd la réactivité
console.log(state2.count); // 10 (valeur correcte, mais réactivité perdue)
// Les modifications ultérieures de state2.count ne déclencheront pas de mise à jour de la vue
Différences clés :
refnécessite.valuepour l'accèsreactiveaccède directement aux propriétésreactivene peut pas être réaffecté, sinon la réactivité est perdue
Question 2 : Problème de déstructuration
Expliquez le problème du code suivant et proposez une solution.
// Cas 1 : Déstructuration de ref
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value;
name = 'Jane'; // ?
// Cas 2 : Déstructuration de reactive
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state;
count = 10; // ?
Cliquez pour voir la réponse
Cas 1 : Déstructuration de ref
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value;
name = 'Jane'; // Ne mettra pas à jour user.value.name
// Bonne pratique : modifier la valeur du ref
user.value.name = 'Jane';
// Ou réaffecter
user.value = { name: 'Jane', age: 30 };
Cas 2 : Déstructuration de reactive
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state;
count = 10; // Perd la réactivité, ne déclenchera pas de mise à jour
// Bonne pratique 1 : modifier directement la propriété
state.count = 10;
// Bonne pratique 2 : utiliser toRefs pour conserver la réactivité
import { toRefs } from 'vue';
const { count, message } = toRefs(state);
count.value = 10; // C'est maintenant un ref, .value est nécessaire
Résumé :
- La déstructuration de valeurs primitives perd la réactivité
- La déstructuration de
reactivenécessitetoRefspour conserver la réactivité - La déstructuration des propriétés d'objet de
refperd aussi la réactivité, il faut modifier.valuedirectement
Question 3 : Choisir ref ou reactive ?
Indiquez si les scénarios suivants devraient utiliser ref ou reactive.
// Scénario 1 : Compteur
const count = ?;
// Scénario 2 : État du formulaire
const form = ?;
// Scénario 3 : Données utilisateur (peut nécessiter une réaffectation)
const user = ?;
// Scénario 4 : Référence de template
const inputRef = ?;
Cliquez pour voir la réponse
// Scénario 1 : Compteur (type primitif)
const count = ref(0); // ref
// Scénario 2 : État du formulaire (objet complexe, pas de réaffectation)
const form = reactive({
username: '',
password: '',
errors: {},
}); // reactive
// Scénario 3 : Données utilisateur (peut nécessiter une réaffectation)
const user = ref({ name: 'John', age: 30 }); // ref (réaffectation possible)
// Scénario 4 : Référence de template
const inputRef = ref(null); // ref (les références de template doivent utiliser ref)
Principes de choix :
- Type primitif ->
ref - Objet nécessitant une réaffectation ->
ref - Référence de template ->
ref - État d'objet complexe sans réaffectation ->
reactive
5. Best Practices
Bonnes pratiques
Pratiques recommandées
// 1. Types primitifs avec ref
const count = ref(0);
const message = ref('Hello');
// 2. États complexes avec reactive
const formState = reactive({
username: '',
password: '',
errors: {},
});
// 3. Réaffectation avec ref
const user = ref({ name: 'John' });
user.value = { name: 'Jane' };
// 4. Déstructuration de reactive avec toRefs
import { toRefs } from 'vue';
const { count, message } = toRefs(state);
// 5. Style uniforme : l'équipe peut choisir d'utiliser principalement ref ou reactive
Pratiques à éviter
// 1. Ne pas utiliser reactive pour les types primitifs
const count = reactive(0); // Erreur
// 2. Ne pas réaffecter reactive
let state = reactive({ count: 0 });
state = { count: 10 }; // Perd la réactivité
// 3. Ne pas déstructurer directement reactive
const { count } = reactive({ count: 0 }); // Perd la réactivité
// 4. Ne pas oublier .value dans le template (cas de ref)
// Pas besoin de .value dans le template, mais nécessaire en JavaScript
6. Interview Summary
Résumé d'entretien
Aide-mémoire
ref :
- Applicable à tout type
- Nécessite
.valuepour l'accès - Peut être réaffecté
- Déballage automatique dans le template
reactive :
- Uniquement pour les objets
- Accès direct aux propriétés
- Ne peut pas être réaffecté
- La déstructuration nécessite
toRefs
Principes de choix :
- Type primitif ->
ref - Besoin de réaffectation ->
ref - État d'objet complexe ->
reactive
Exemples de réponses en entretien
Q: Quelle est la différence entre ref et reactive ?
"ref et reactive sont deux API de Vue 3 pour créer des données réactives. Les principales différences incluent : 1) Types applicables : ref peut être utilisé pour tout type, reactive uniquement pour les objets ; 2) Mode d'accès : ref nécessite .value, reactive accède directement aux propriétés ; 3) Réaffectation : ref peut être réaffecté, reactive ne le peut pas sous peine de perdre la réactivité ; 4) Déstructuration : la déstructuration de reactive nécessite toRefs pour conserver la réactivité. En général, on utilise ref pour les types primitifs et les objets nécessitant une réaffectation, et reactive pour les états d'objets complexes."
Q: Quand utiliser ref ? Quand utiliser reactive ?
"Utiliser ref : 1) valeurs de types primitifs ; 2) objets nécessitant une réaffectation ; 3) références de template. Utiliser reactive : 1) états d'objets complexes avec plusieurs propriétés associées ; 2) états ne nécessitant pas de réaffectation. En pratique, beaucoup d'équipes utilisent uniformément ref car il est plus flexible et applicable à un plus large éventail de cas."