WATCH EN VUE.JS: CÓMO OBSERVAR CAMBIOS Y EJEMPLOS
La reactividad con watch en vuejs es una opción de la API de VueJS que permite observar cambios en propiedades reactivas (como ref, reactive o computed) y ejecutar una función cuando estas cambian. Es útil para realizar efectos secundarios, como hacer peticiones a una API, actualizar otras partes de la aplicación, o realizar cálculos complejos en respuesta a un cambio. Hay que usarwatch cuando se necesita reaccionar a cambios específicos en una o más propiedades, si se requiere acceso a los valores anterior y nuevo y para efectos secundarios complejos, como hacer una llamada a una API cuando cambia un filtro.Opciones de Watch
Se puede pasar un objeto de opciones para personalizar el comportamiento de watch.
- immediate: true: Ejecuta el callback inmediatamente con el valor actual.
- deep: true: Observa cambios profundos en objetos o arreglos anidados.
- flush: Controla cuándo se ejecuta el callback en relación con las actualizaciones del DOM (pre, post, o sync).
Ejemplo sencillo:
import { ref, watch } from 'vue';
export default {
setup() {
const contador = ref(0);
watch(contador, (nuevoValor) => {
console.log(`Contador cambió a ${nuevoValor}`);
}, { immediate: true }); // Se ejecuta inmediatamente
return { contador };
}
};
Ejemplo de como detener un watch: En la Composition API, watch devuelve una función que puedes usar para detener la observación:
import { ref, watch } from 'vue';
export default {
setup() {
const contador = ref(0);
const detenerWatch = watch(contador, (nuevoValor) => {
console.log(`Contador: ${nuevoValor}`);
});
// Detener el watch después de 5 segundos
setTimeout(() => {
detenerWatch();
console.log('Watcher detenido');
}, 5000);
return { contador };
}
};
Dieferencias entre watch y watchEffect
- watch: Observa específicamente una o más fuentes reactivas y solo se ejecuta cuando estas cambian. Permite acceder a los valores nuevo y anterior.
- watchEffect: Ejecuta una función inmediatamente y rastrea automáticamente todas las dependencias reactivas usadas dentro de ella. No necesitas especificar qué observar.
Ejemplo de watchEffect
import { ref, watchEffect } from 'vue';
export default {
setup() {
const contador = ref(0);
watchEffect(() => {
console.log(`Contador cambió a ${contador.value}`);
});
return { contador };
}
};
Ejemplo práctico: Llamada a una API
import { ref, watch } from 'vue';
import axios from 'axios';
export default {
setup() {
const filtro = ref('');
const resultados = ref([]);
watch(filtro, async (nuevoFiltro) => {
const response = await axios.get(`https://api.example.com/buscar?q=${nuevoFiltro}`);
resultados.value = response.data;
}, { immediate: true });
return { filtro, resultados };
}
};
import { ref, watch } from 'vue';
export default {
setup() {
const contador = ref(0);
watch(contador, (nuevoValor) => {
console.log(`Contador cambió a ${nuevoValor}`);
}, { immediate: true }); // Se ejecuta inmediatamente
return { contador };
}
};
import { ref, watch } from 'vue';
export default {
setup() {
const contador = ref(0);
const detenerWatch = watch(contador, (nuevoValor) => {
console.log(`Contador: ${nuevoValor}`);
});
// Detener el watch después de 5 segundos
setTimeout(() => {
detenerWatch();
console.log('Watcher detenido');
}, 5000);
return { contador };
}
};
- watch: Observa específicamente una o más fuentes reactivas y solo se ejecuta cuando estas cambian. Permite acceder a los valores nuevo y anterior.
- watchEffect: Ejecuta una función inmediatamente y rastrea automáticamente todas las dependencias reactivas usadas dentro de ella. No necesitas especificar qué observar.
import { ref, watchEffect } from 'vue';
export default {
setup() {
const contador = ref(0);
watchEffect(() => {
console.log(`Contador cambió a ${contador.value}`);
});
return { contador };
}
};
import { ref, watch } from 'vue';
import axios from 'axios';
export default {
setup() {
const filtro = ref('');
const resultados = ref([]);
watch(filtro, async (nuevoFiltro) => {
const response = await axios.get(`https://api.example.com/buscar?q=${nuevoFiltro}`);
resultados.value = response.data;
}, { immediate: true });
return { filtro, resultados };
}
};