Propiedades de observación en Vue3
En este capítulo, presentaremos las propiedades de observación de Vue3watch, podemos usarwatchpara responder a los cambios de datos.
watchLa función de watch es monitorear los cambios en las propiedades reactivas y ejecutar operaciones específicas cuando las propiedades cambian. Es un mecanismo reactivo en Vue que te permite responder a los cambios de datos y ejecutar lógica personalizada.
watchEsto proporciona más control y flexibilidad cuando cambian las propiedades reactivas, permitiendo que tus componentes respondan mejor a los cambios de datos y ejecuten la lógica correspondiente.
El siguiente ejemplo implementa un contador usando watch:
Ejemplo
<p style = "font-size:25px;">Contador: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">Haz clic</button>
</div>
<script>
const app = {
data() {
return {
counter: 1
}
}
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('counter', function(nval, oval) {
alert('Cambio del valor del contador :' + oval + ' se convierte en ' + nval + '!');
});
</script>
Pruébalo »
El siguiente ejemplo realizakilómetrosyArrozla conversión entre:
Ejemplo
kilómetros: <input type = "text" v-model = "kilometers" @focus="currentlyActiveField = 'kilometers'">
Arroz: <input type = "text" v-model = "meters" @focus="currentlyActiveField = 'meters'">
</div>
<p id="info"></p>
<script>
const app = {
data() {
return {
kilometers : 0,
meters:0
}
},
watch : {
kilometers:function(newValue, oldValue) {
// Verifica si es el campo de entrada actual
if (this.currentlyActiveField === 'kilometers') {
this.meters = newValue * 1000
}
},
meters : function (newValue, oldValue) {
// Verifica si es el campo de entrada actual
if (this.currentlyActiveField === 'meters') {
this.kilometers = newValue/ 1000;
}
}
}
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('kilometers', function (newValue, oldValue) {
// Esta devolución de llamada se invocará cuando vm.kilometers cambie
document.getElementById ("info").innerHTML = "Valor antes de la modificación: " + oldValue + ", el valor después de la modificación es: " + newValue;
})
</script>
Pruébalo »
Haz clic en el botón "Pruébalo" para ver el ejemplo en línea
En el código anterior, creamos dos campos de entrada. En la propiedad data, los valores iniciales de kilometers y meters son ambos 0. El objeto watch crea dos métodos de supervisión para el objeto data: kilometers y meters.
Cuando ingresamos datos en el campo de entrada, watch monitorea los cambios de datos en tiempo real y actualiza su propio valor. Puedes ver la siguiente demostración en video:
Usar watch en la carga asíncrona
Para la carga de datos asíncronos, Vue proporciona un método más general a través de la opción watch para responder a los cambios de datos.
En el siguiente ejemplo usamos la librería axios, que se presentará en detalle más adelante.
Ejemplo
<!--estas funciones para mantenerse simple. Esto también te permite elegir libremente las herramientas con las que estás más familiarizado.-->
<script src="https://cdn.staticfile.org/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/3.2.37/vue.global.min.js"></script>
<script>
const watchExampleVM = Vue.createApp({
data() {
return {
question: '',
answer: 'Cada pregunta debe terminar con un signo ?.'
}
},
watch: {
// Cada vez que la pregunta cambie, esta función se ejecutará, terminando con el signo ?, compatible con el ? en chino e inglés.
question(newQuestion, oldQuestion) {
if (newQuestion.indexOf('?') > -1 || newQuestion.indexOf('?') > -1) {
this.getAnswer()
}
}
},
methods: {
getAnswer() {
this.answer = 'Cargando...'
axios
.get('/try/ajax/json_vuetest.php')
.then(response => {
this.answer = response.data.answer
})
.catch(error => {
this.answer = '¡Error! No se puede acceder a la API. ' + error
})
}
}
}).mount('#watch-example')
</script>
Pruébalo »
Resumen de uso
watch es un mecanismo de observación de datos reactivos proporcionado por Vue 3, que puede observar una o múltiples propiedades.
Puedes manejar los cambios de datos pasando una función de devolución de llamada, y admite opciones como observación profunda y ejecución inmediata.
1. Uso básico
En Vue 3, la función watch se usa para observar propiedades reactivas.
Cuando el valor de la propiedad observada cambia, Vue activa la ejecución de la función de devolución de llamada.
Ejemplo
export default {
setup() {
const state = reactive({
count: 0
});
watch(
() => state.count, // Propiedad observada
(newVal, oldVal) => { // Función de devolución de llamada al cambiar
console.log(`count changed from ${oldVal} to ${newVal}`);
}
);
return {
state
};
}
};
2. Observar múltiples propiedades reactivas
Si deseas observar varias propiedades reactivas a la vez, puedes pasar un array con las propiedades a observar:
Ejemplo
export default {
setup() {
const state = reactive({
count: 0,
name: 'Vue3'
});
watch(
[() => state.count, () => state.name], // Observar múltiples propiedades
([newCount, newName], [oldCount, oldName]) => {
console.log(`count changed from ${oldCount} to ${newCount}`);
console.log(`name changed from ${oldName} to ${newName}`);
}
);
return {
state
};
}
};
3. Observación profunda
Si lo que quieres observar es un objeto o un array, y deseas observar sus propiedades anidadas, puedes usardeep: truela opción. Esto observará todos los cambios de propiedades del objeto.
Ejemplo
export default {
setup() {
const state = reactive({
user: {
name: 'Alice',
age: 25
}
});
watch(
() => state.user, // Observar el objeto completo
(newVal, oldVal) => {
console.log('User object changed:', newVal, oldVal);
},
{ deep: true } // Habilitar la observación profunda
);
return {
state
};
}
};
4. Ejecución inmediata
De forma predeterminada, watch solo activa la devolución de llamada cuando el valor observado cambia. Si deseas que la devolución de llamada se ejecute inmediatamente al cargar el componente, puedes configurarimmediate: true。
Ejemplo
export default {
setup() {
const state = reactive({
count: 0
});
watch(
() => state.count, // Propiedad observada
(newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`);
},
{ immediate: true } // Ejecución inmediata
);
return {
state
};
}
};
5. Operaciones asíncronas
Si necesitas realizar operaciones asíncronas en watch, puedes usar async y await directamente en la función de devolución de llamada, lo que te permite manejar operaciones como solicitudes a API, almacenamiento de datos, etc.
Ejemplo
export default {
setup() {
const state = reactive({
count: 0
});
watch(
() => state.count,
async (newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`);
// Supongamos que se realiza una solicitud asíncrona
await fetch(`https://api.example.com/count/${newVal}`);
}
);
return {
state
};
}
};
6. Observar múltiples propiedades y usar la función handler
También puedes usar watch como un controlador para observar múltiples propiedades, así:
Ejemplo
export default {
setup() {
const state = reactive({
count: 0,
name: 'Vue3'
});
const handler = ([newCount, newName], [oldCount, oldName]) => {
console.log(`count changed: ${oldCount} → ${newCount}`);
console.log(`name changed: ${oldName} → ${newName}`);
};
watch([() => state.count, () => state.name], handler);
return {
state
};
}
};
7. watchEffect: una versión simplificada de observación
Vue 3 también proporciona la API watchEffect, que es más concisa que watch, ya que puede rastrear automáticamente los cambios en los datos reactivos sin necesidad de especificar una fuente de datos concreta.
Ejemplo
export default {
setup() {
const state = reactive({
count: 0
});
watchEffect(() => {
console.log(`count is: ${state.count}`);
});
return {
state
};
}
};
watchEffect detectará automáticamentestate.countlos cambios y activará la devolución de llamada cuando estos ocurran.
8. Opción flush
La opción flush se usa para controlar el momento en que se ejecuta la devolución de llamada de watch.
De forma predeterminada, la devolución de llamada de watch se ejecuta después de la actualización del DOM. Si necesitas ejecutar la devolución de llamada antes de la actualización, puedes usarflush: 'pre'。
Ejemplo
export default {
setup() {
const state = reactive({
count: 0
});
watch(
() => state.count,
(newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`);
},
{ flush: 'pre' } // Ejecutar la devolución de llamada antes de la actualización
);
return {
state
};
}
};