[Medium] ref vs reactive
1. Cosa sono ref e reactive?
Cosa sono
refereactive?
ref e reactive sono due API fondamentali nella Composition API di Vue 3 per creare stato reattivo.
ref
Definizione: ref crea un wrapper reattivo per un valore primitivo o un riferimento a oggetto.
Clicca per espandere l'esempio base di ref
<script setup>
import { ref } from 'vue';
// primitivi
const count = ref(0);
const message = ref('Hello');
const isActive = ref(true);
// anche gli oggetti funzionano con ref
const user = ref({
name: 'John',
age: 30,
});
// accesso con .value in JavaScript
console.log(count.value); // 0
count.value++;
</script>
reactive
Definizione: reactive crea un proxy oggetto reattivo (non per valori primitivi direttamente).
Clicca per espandere l'esempio base di reactive
<script setup>
import { reactive } from 'vue';
const state = reactive({
count: 0,
message: 'Hello',
user: {
name: 'John',
age: 30,
},
});
// accesso diretto alle proprietà
console.log(state.count); // 0
state.count++;
</script>
2. ref vs reactive: Differenze Principali
Differenze principali tra
refereactive
1. Tipi supportati
ref: funziona con qualsiasi tipo.
const count = ref(0); // number
const message = ref('Hello'); // string
const isActive = ref(true); // boolean
const user = ref({ name: 'John' }); // oggetto
const items = ref([1, 2, 3]); // array
reactive: funziona con oggetti (inclusi array), non con primitivi.
const state = reactive({ count: 0 }); // oggetto
const list = reactive([1, 2, 3]); // array
const count = reactive(0); // utilizzo non valido
const message = reactive('Hello'); // utilizzo non valido
2. Stile di accesso
ref: usare .value in JavaScript.
Clicca per espandere l'esempio di accesso ref
<script setup>
import { ref } from 'vue';
const count = ref(0);
console.log(count.value);
count.value = 10;
</script>
<template>
<div>{{ count }}</div>
<!-- auto-unwrapped nel template -->
</template>
reactive: accesso diretto alle proprietà.
Clicca per espandere l'esempio di accesso reactive
<script setup>
import { reactive } from 'vue';
const state = reactive({ count: 0 });
console.log(state.count);
state.count = 10;
</script>
<template>
<div>{{ state.count }}</div>
</template>
3. Comportamento alla riassegnazione
ref: può essere riassegnato.
const user = ref({ name: 'John' });
user.value = { name: 'Jane' }; // valido
reactive: non dovrebbe essere riassegnato a un nuovo binding di variabile oggetto.
let state = reactive({ count: 0 });
state = { count: 10 }; // perde la connessione reattiva
4. Destrutturazione
ref: destrutturare ref.value restituisce valori semplici (non reattivi).
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value; // valori semplici
reactive: la destrutturazione diretta perde la reattività.
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state; // perde la reattività
import { toRefs } from 'vue';
const refs = toRefs(state);
// refs.count e refs.message mantengono la reattività
3. Quando usare ref vs reactive?
Quando dovresti scegliere ciascuna API?
Usa ref quando
- Lo stato è primitivo.
const count = ref(0);
const message = ref('Hello');
- Potresti sostituire l'intero valore/oggetto.
const user = ref({ name: 'John' });
user.value = { name: 'Jane' };
- Hai bisogno di template refs.
<template>
<div ref="container"></div>
</template>
<script setup>
const container = ref(null);
</script>
- Vuoi uno stile
.valuecoerente per tutti i valori.
Usa reactive quando
- Gestisci stato oggetto complesso.
const formState = reactive({
username: '',
password: '',
errors: {},
});
- Raggruppi campi correlati insieme senza sostituire l'identità dell'oggetto.
const userState = reactive({
user: null,
loading: false,
error: null,
});
- Preferisci l'accesso diretto alle proprietà per strutture annidate.
4. Domande Comuni nei Colloqui
Domande comuni nei colloqui
Domanda 1: differenze base
Spiega output e comportamento:
// caso 1: ref
const count1 = ref(0);
count1.value = 10;
console.log(count1.value); // ?
// caso 2: reactive
const state = reactive({ count: 0 });
state.count = 10;
console.log(state.count); // ?
// caso 3: riassegnazione reactive
let state2 = reactive({ count: 0 });
state2 = { count: 10 };
console.log(state2.count); // ?
Clicca per vedere la risposta
console.log(count1.value); // 10
console.log(state.count); // 10
console.log(state2.count); // 10 (il valore esiste ma non è più reattivo)
Punti chiave:
refrichiede.valuereactiveusa l'accesso diretto alle proprietà- riassegnare il binding dell'oggetto
reactiveinterrompe il tracciamento reattivo
Domanda 2: trappola della destrutturazione
Cosa c'è di sbagliato qui e come correggerlo?
// caso 1: destrutturazione ref
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value;
name = 'Jane'; // ?
// caso 2: destrutturazione reactive
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state;
count = 10; // ?
Clicca per vedere la risposta
Caso 1 (ref):
const user = ref({ name: 'John', age: 30 });
const { name, age } = user.value;
name = 'Jane'; // non aggiorna user.value.name
// corretto
user.value.name = 'Jane';
// oppure
user.value = { name: 'Jane', age: 30 };
Caso 2 (reactive):
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = state;
count = 10; // perde la reattività
// approccio corretto 1
state.count = 10;
// approccio corretto 2
import { toRefs } from 'vue';
const refs = toRefs(state);
refs.count.value = 10;
Riepilogo:
- i valori semplici destrutturati non sono reattivi
- usare
toRefsper la destrutturazione di oggetti reattivi
Domanda 3: scegliere ref o reactive
Scegli l'API per ogni scenario:
// Scenario 1: contatore
const count = ?;
// Scenario 2: stato del form
const form = ?;
// Scenario 3: oggetto utente che potrebbe essere sostituito
const user = ?;
// Scenario 4: template ref
const inputRef = ?;
Clicca per vedere la risposta
const count = ref(0); // primitivo
const form = reactive({
username: '',
password: '',
errors: {},
}); // stato oggetto raggruppato
const user = ref({ name: 'John', age: 30 }); // sostituzione completa più facile
const inputRef = ref(null); // i template ref devono usare ref
Regola pratica:
- primitivo ->
ref - sostituzione completa dell'oggetto necessaria ->
ref - stato oggetto complesso raggruppato ->
reactive - template refs ->
ref
5. Best Practices (Buone Pratiche)
Buone pratiche
Raccomandato
// 1) primitivi con ref
const count = ref(0);
const message = ref('Hello');
// 2) stato oggetto strutturato con reactive
const formState = reactive({
username: '',
password: '',
errors: {},
});
// 3) usare ref quando la sostituzione completa è comune
const user = ref({ name: 'John' });
user.value = { name: 'Jane' };
// 4) usare toRefs quando si destruttura un oggetto reactive
import { toRefs } from 'vue';
const { username, password } = toRefs(formState);
Da evitare
// 1) non usare reactive per primitivi
const count = reactive(0); // non valido
// 2) non riassegnare il binding reactive
let state = reactive({ count: 0 });
state = { count: 10 }; // interrompe il tracciamento
// 3) evitare la destrutturazione diretta di reactive quando serve la reattività
const { count } = reactive({ count: 0 }); // perde il tracciamento
6. Riepilogo per i Colloqui
Riepilogo per i colloqui
Promemoria rapido
ref:
- qualsiasi tipo
.valuein JavaScript- sostituzione completa facile
- auto-unwrapped nel template
reactive:
- solo oggetti/array
- accesso diretto alle proprietà
- mantiene l'identità dell'oggetto
- usare
toRefsper la destrutturazione
Guida alla scelta:
- primitivo ->
ref - oggetto con sostituzione frequente ->
ref - stato oggetto raggruppato ->
reactive
Risposta esempio
D: Qual è la differenza tra ref e reactive?
refavvolge un valore e vi si accede tramite.valuein JavaScript, mentrereactiverestituisce un oggetto proxy con accesso diretto alle proprietà.reffunziona con primitivi e oggetti;reactiveè per oggetti/array. Riassegnareref.valueè valido; riassegnare un bindingreactiveinterrompe il tracciamento.
D: Quando dovrei usare ciascuno?
Usare
refper primitivi, template refs e stati oggetto che vengono spesso sostituiti interamente. Usarereactiveper stato oggetto complesso raggruppato dove è preferita un'identità dell'oggetto stabile.