He estado usando Vue durante un tiempo, y mi experiencia siempre ha sido un método que volverá a calcular si se actualizan sus datos reactivos subyacentes. He encontrado información contradictoria sobre SO:
- Intentaba responder a esta pregunta , y me dijeron varias veces que este no era el caso.
- La respuesta aceptada aquí indica que "[un método] solo se evaluará cuando lo llame explícitamente".
Busqué en los documentos y no vi nada increíblemente claro.
Si no son reactivos, ¿por qué funciona este ejemplo?
<ul>
<li v-for="animal in animals" :key="animal.id">
<span v-if="isAwesome(animal)">{{ animal.name }}</span>
</li>
</ul>
export default {
data() {
return {
awesomeAnimalIds: [],
animals: [
{ id: 1, name: 'dog' },
{ id: 5, name: 'cat' },
{ id: 9, name: 'fish' },
],
};
},
created() {
setTimeout(() => {
this.awesomeAnimalIds.push(5);
}, 1000);
setTimeout(() => {
this.awesomeAnimalIds.push(9);
}, 2000);
},
methods: {
isAwesome(animal) {
return this.awesomeAnimalIds.includes(animal.id);
},
},
};
Realmente me gustaría tener una respuesta definitiva y satisfactoria a la que esta comunidad pueda referirse.
Respuestas:
Según cómo se rastrean los cambios desde los documentos, esto es lo que está sucediendo:
Se crea un observador especial para la instancia del componente para determinar cuándo se requiere una nueva representación.
Vue convierte todas las propiedades de
data
getters y setters.isAwesome
la plantilla.isAwesome
,awesomeAnimalIds
se invoca al captador para .awesomeAnimalIds
campo dedata
.awesomeAnimalIds
se actualiza, lo que invoca alawesomeAnimalIds
configurador.data
campo que recibió una notificación, se activa una nueva representación.A partir de este y este ejemplo anterior, podemos concluir lo siguiente:
Existe una idea errónea común de que los métodos se "invocan solo una vez" o "dispara y olvida" cuando se llama desde una plantilla. Claramente, este no es siempre el caso porque los métodos pueden establecer una dependencia reactiva .
Entonces, ¿cuándo debemos usar una propiedad calculada frente a un método?
Consulte la sección de la guía sobre el almacenamiento en caché calculado frente a los métodos . Aquí está mi opinión al respecto:
fetch
desde ellos.fuente
No, los métodos no son reactivos. Solo los datos pueden ser reactivos en Vue.
PERO es importante entender cómo funciona Vue ...
data()
miembros (lo hace todo el tiempo, no solo durante el primer renderizado). Si se accede a alguno de los datos durante el procesamiento, Vue sabe que el contenido de este miembro de datos influye en el resultado del procesamiento.No importa si hace referencia al miembro de datos directamente, úselo en
computed
o en unmethod
. Si los datos se "tocan" durante la representación, el cambio de los datos desencadenará una nueva representación en el futuro ...fuente
Este es un caso muy interesante.
De lo que he leído y de mi experiencia puedo decir que: No, los métodos no son inherentemente reactivos. Se debe llamar explícitamente a un método para que se ejecute.
Pero, ¿cómo puedo explicar su caso? Puse su código en una caja de arena y, efectivamente, a medida que inserta los identificadores en la matriz, la plantilla se actualiza para mostrar el nombre del animal. Esto indicaría cierta reactividad. ¿Lo que da?
Bueno, hice un experimento. Agregué un simple
div
a cada ciclo que genera un número aleatorio cuando se genera.Y lo que vi fue que cada vez que se introducía una nueva identificación en la matriz, todos los números aleatorios cambiaban. Esta es la clave para entender por qué "parece" que el método
isAwesome
es reactivo.De alguna manera, cuando se empuja una nueva ID a la matriz, Vue vuelve a representar el bucle por completo y, por lo tanto, ejecuta los métodos nuevamente. No puedo explicar el funcionamiento interno de por qué vue vuelve a representar todo el ciclo, eso requeriría más investigación.
Entonces para responder a tu pregunta.
isAwesome
no es reactivo, es simplemente una ilusión creada por la reproducción del bucle.fuente
update
que causare-render