Reactividad, Vue.js Composition API
La reactividad en Vue.js es el mecanismo que permite que los datos y la interfaz de usuario se mantengan sincronizados automáticamente. Esto significa que cuando un valor cambia, todas las partes de la aplicación que dependen de él se actualizan sin necesidad de intervención manual.
En JavaScript puro, no hay una manera sencilla de detectar cambios en una variable a menos que se programe una función para monitorizar. Sin embargo, Vue.js nos facilita esto con ref()
y reactive()
.
Declarando variables reactivas con ref()
Vue.js nos proporciona la función ref()
para hacer que una variable simple (como un número, cadena o booleano) sea reactiva.
Ejemplo usando ref()
<template>
<h1>App</h1>
<input type="text" v-model="mensaje">
<p>{{mensaje}}</p>
</template>
<script setup>
import {ref} from 'vue';
const mensaje = ref('Aqui aparece el mensaje');
</script>
Explicacion
Enlazamos la variable mensaje usando v-model,esto nos permite que el valor que contenga el input sera el valor de la variable mensaje
<input type="text" v-model="mensaje">
en esta linea declaramos la variable mensaje y gracias a ref() es reactiva,
const mensaje = ref('Aqui aparece el mensaje');
Al ingresar texto en el input el valor de el mensaje cambia automáticamente,sin la necesidad de hacerlo manualmente a esto se le llama reactividad
.
Ejemplo usando computed()
computed también es un tipo de reactividad,se usan para definir propiedades calculadas que dependen de otras propiedades reactivas,estas se actualizan automáticamente cuando los valores de las propiedades de las que dependen cambian por ejemplo
<template>
<h1>App</h1>
<input type="number" v-model="numero1">
<input type="number" v-model="numero2">
<p>Numero 1 => {{numero1}}</p>
<p>Numero 2 => {{numero2}}</p>
<p>Resultado => {{resultado}}</p>
</template>
<script setup>
import {ref,computed} from 'vue';
const numero1 = ref(0);
const numero2= ref(0);
const resultado = computed(()=>numero1.value+numero2.value);
</script>
al declarar la variable resultado como computed()
esta es reactiva y cambiara su valor cada vez que cambie el valor de numero1 o numero2,computed()
memoriza el resultado y solo se vuelve a calcular cuando cambian sus dependencias.
const resultado = computed(()=>numero1.value+numero2.value);
uso de .value
como se puede observar, al calcular
el resultado accedemos al valor de cada propiedad reactiva de la que este depende utilizando.value
, esto se debe a que cuando declaramos numero1 y numero2 como ref()
, vue.js
crea un objeto con una sola propiedad,en este caso value
, esta propiedad value
es la que almacena el valor interna de la variable reactiva,por lo tanto para acceder o modificar el valor,se necesita usar .value
.
Ejemplo usando watch()
watch()
observa una variable reactiva y este ejecuta una función cuando su valor cambie,
<template>
<h1>App</h1>
<button @click="incrementarContador">Incrementar Contador</button>
<p>contador => {{contador}}</p>
</template>
<script setup>
import {ref,watch} from 'vue';
const contador = ref(0);
watch(contador,(nuevoValor,anteriorValor)=>{
console.log(`el valor del contador cambio de ${anteriorValor} a ${nuevoValor}`);
});
const incrementarContador = ()=>{
contador.value++;
};
</script>
Explicación
- Se define contador como una variable reactiva:
const contador = ref(0);
- Se usa
watch(contador, (nuevoValor, anteriorValor) => {...})
para ejecutar una acción cada vez que contador cambie. - Dentro de
watch()
, nuevoValor almacena el valor actualizado y anteriorValor almacena el valor anterior. Estos valores solo existen dentro de watch().
Cada vez que se hace clic en el botón, el contador cambia y watch()
se ejecuta.
Ejemplo 2 de watch()
<template>
<h1>App</h1>
<p>contador => {{contador}}</p>
</template>
<script setup>
import {ref,watch} from 'vue';
let contador = ref(0);
watch(contador,(nuevoValor,anteriorValor)=>{
console.log(`El valor del contador cambio de ${anteriorValor} a ${nuevoValor}`);
});
setInterval(() => {
contador.value++;
if(contador.value >= 10){
contador.value=0;
}
}, 1000);
</script>
Explicacion
con la función setInterval() se incrementa el valor del contador cada segundo y cuando el contador es igual o mayor que 10,se reinicia a 0,watch() registra los cambios en la consola.
watchEffect()
¿que es watchEffect()?
es similar a watch()
,pero con la diferencia que no necesita especificar que variable reactiva quieres observar,se ejecuta inmediatamente y rastrea cualquier valor reactivo dentro de su función,entonces cada vez que una variable que hayamos declarado como reactiva dentro de su función este se ejecutara.
Ejemplo usando watchEffect()
<template>
<h1>App</h1>
<button @click="incrementar">Incrementar Contador</button>
<p>Contador: {{contador}}</p>
</template>
<script setup>
import { ref, watchEffect } from 'vue';
const contador = ref(0);
watchEffect(() => {
console.log(`El contador cambió de valor a: ${contador.value}`);
});
const incrementar = () => {
contador.value++;
};
</script>
Explicación
iniciamos la variable contador
const contador = ref(0);
con las siguientes lineas, rastreamos el valor que ah cambiado sin especificarlo en el watch
y cada vez que el valor del contador incremente,por ende este cambie disparar el watchEffect()
y mostrara en consola un mensaje,describiendo el cambio.
watchEffect(() => {
console.log(`El contador cambió de valor a: ${contador.value}`);
});
con la funcion incrementar()
incrementamos el valor del contador de a 1
const incrementar = () => {
contador.value++;
};
Ejemplo con mas de una variable reactiva
<template>
<h1>App</h1>
<button @click="incrementar">Incrementar Contador</button>
<p>Contador: {{contador}}</p>
</template>
<script setup>
import { ref, watchEffect } from 'vue';
const contador = ref(0);
const contador2 = ref(0);
watchEffect(() => {
console.log(`los contadores cambiaron su valor a: contador 1 ${contador.value} y contador 2 ${contador2.value}`);
});
const incrementar = () => {
contador.value++;
contador2.value=contador2.value+2;
};
</script>
No es mas que una modificación del anterior ejemplo,se crea un segundo contador que incrementa de a 2 y al igual que con el primer contador al cambiar de valor se ejecuta el watchEffect() automáticamente al cambiar los valores.
¿Cuándo usar watchEffect()
?
- Cuando quieres ejecutar código cada vez que cambie alguna dependencia sin declararlas manualmente.
- Para operaciones como sincronizar datos, llamadas a APIs o manipular elementos del DOM.
- Cuando necesitas que la función se ejecute inmediatamente al montarse el componente.
reactive()
reactive()
es una función de Vue 3 que permite crear objetos reactivos. Es decir, convierte un objeto y todas sus propiedades en reactivas, de modo que cualquier cambio en ellas será detectado automáticamente por Vue. A diferencia de ref()
, que se usa para valores únicos como números o cadenas, reactive()
se usa cuando necesitamos manejar objetos completos con múltiples propiedades.
Ejemplo
<template>
<h1>App</h1>
<button @click="cambiarDatos">Cambiar persona</button>
<p>Nombre: {{persona.nombre}}</p>
<p>Edad: {{persona.edad}}</p>
</template>
<script setup>
import {reactive } from 'vue';
const persona = reactive({
nombre:'jose',
edad:30,
});
const cambiarDatos = () => {
persona.nombre = 'dan';
persona.edad = 25;
console.log(`Nuevo nombre: ${persona.nombre}, Nueva edad: ${persona.edad}`);
};
</script>
Explicación
se crea un objeto,el objeto persona con dos propiedades nombre y edad que ya con sus valores
const persona = reactive({
nombre:'jose',
edad:30,
});
con la funcion cambiardatos(),modificamos los valores del nombre y la edad
const cambiarDatos = () => {
persona.nombre = 'dan';
persona.edad = 25;
console.log(`Nuevo nombre: ${persona.nombre}, Nueva edad: ${persona.edad}`);
};
Conclusión
Vue.js simplifica la reactividad con ref()
, computed()
, watch()
y reactive(), permitiendo que los datos y la interfaz de usuario se mantengan sincronizados automáticamente. Mientras que ref()
convierte variables en reactivas, computed()
permite crear valores derivados de manera eficiente, y watch()
nos ayuda a reaccionar a cambios en los datos.