Estoy tratando de entender cómo observar adecuadamente alguna variación de utilería. Tengo un componente primario (archivos .vue) que recibe datos de una llamada ajax, coloca los datos dentro de un objeto y lo usa para representar algún componente secundario a través de una directiva v-for, debajo de una simplificación de mi implementación:
<template>
<div>
<player v-for="(item, key, index) in players"
:item="item"
:index="index"
:key="key"">
</player>
</div>
</template>
... luego dentro de la <script>
etiqueta:
data(){
return {
players: {}
},
created(){
let self = this;
this.$http.get('../serv/config/player.php').then((response) => {
let pls = response.body;
for (let p in pls) {
self.$set(self.players, p, pls[p]);
}
});
}
Los objetos objeto son así:
item:{
prop: value,
someOtherProp: {
nestedProp: nestedValue,
myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
},
}
Ahora, dentro del componente "jugador" de mi hijo, estoy tratando de ver la variación de propiedad de cualquier artículo y uso:
...
watch:{
'item.someOtherProp'(newVal){
//to work with changes in "myArray"
},
'item.prop'(newVal){
//to work with changes in prop
}
}
Funciona pero me parece un poco complicado y me preguntaba si esta es la forma correcta de hacerlo. Mi objetivo es realizar alguna acción cada vez que prop
cambia u myArray
obtiene nuevos elementos o alguna variación dentro de los existentes. Cualquier sugerencia será apreciada.
fuente
"item.someOtherProp": function (newVal, oldVal){
como @Ron sugirió.keys
interior de un objeto? Ejemplo:"item.*": function(val){...}
Respuestas:
Puede usar un observador profundo para eso:
Esto detectará ahora cualquier cambio en los objetos de la
item
matriz y adiciones a la matriz misma (cuando se usa con Vue.set ). Aquí hay un JSFiddle: http://jsfiddle.net/je2rw3rs/EDITAR
Si no desea ver cada cambio en el objeto de nivel superior, y solo desea una sintaxis menos incómoda para ver objetos anidados directamente, simplemente puede ver un
computed
en su lugar:Aquí está el JSFiddle: http://jsfiddle.net/oa07r5fw/
fuente
computed
en su lugar: jsfiddle.net/c52nda7xwatch: { 'item.foo' : function(newVal, oldVal) { // do work here }}
bastante hábil. ¡Amo a Vue!Otro buen enfoque y uno que es un poco más elegante es el siguiente:
(Aprendí este enfoque de @peerbolte en el comentario aquí )
fuente
ES5
sintaxis. Por supuesto, podríamos argumentar que elES2015 method definition
sí mismo no es muy elegante, pero de alguna manera pierde el punto de la pregunta, que es cómo evitar envolver el nombre con comillas. Supongo que la mayoría de la gente está pasando por alto la pregunta original, que ya contiene la respuesta, y en realidad se está buscando algo que, como usted dice, no está muy bien documentada,Vigilancia profunda de VueJs en objetos secundarios
fuente
Puede usar el "observador dinámico":
El
$watch
devuelve una función de desbloqueo que dejará de ver si se llama.También puedes usar la
deep
opción:Asegúrate de consultar los documentos
fuente
Note that you should not use an arrow function to define a watcher (e.g. searchQuery: newValue => this.updateAutocomplete(newValue)). The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect and this.updateAutocomplete will be undefined.
No lo veo mencionado aquí, pero también es posible usar el
vue-property-decorator
patrón si está ampliando suVue
clase.fuente
Otra forma de agregar que solía 'hackear' esta solución era hacer esto: configuré un
computed
valor separado que simplemente devolvería el valor del objeto anidado.fuente
Mi problema con la respuesta aceptada de usar
deep: true
es que cuando observo una matriz en profundidad, no puedo identificar fácilmente qué elemento de la matriz contiene el cambio. La única solución clara que he encontrado es esta respuesta, que explica cómo hacer un componente para que pueda ver cada elemento de la matriz de forma individual.fuente
oldVal
ynewVal
ambos hacen referencia al mismo objeto, por lo que son lo mismo). La intención de adeep watcher
es hacer algo cuando los valores cambian, como emitir un evento, hacer una llamada ajax, etc. De lo contrario, probablemente desee un componente, como se señala en la respuesta de Mani.Seguimiento de elementos modificados individuales en una lista
Si desea ver todos los elementos de una lista y saber qué elemento de la lista cambió, puede configurar observadores personalizados en cada elemento por separado, de esta manera:
Si su lista no se llena de inmediato (como en la pregunta original), puede mover la lógica
created
a donde sea necesario, por ejemplo, dentro del.then()
bloque.Viendo una lista cambiante
Si su propia lista se actualiza para tener elementos nuevos o eliminados, he desarrollado un patrón útil que "superficial" observa la lista en sí, y observa / desbloquea dinámicamente los elementos a medida que la lista cambia:
fuente
Ninguna de las respuestas para mí estaba funcionando. En realidad, si desea ver datos anidados con componentes que se llaman varias veces. Entonces se les llama con diferentes accesorios para identificarlos. Por ejemplo,
<MyComponent chart="chart1"/> <MyComponent chart="chart2"/>
mi solución es crear una variable de estado vuex adicional, que actualizo manualmente para señalar la propiedad que se actualizó por última vez.Aquí hay un ejemplo de implementación de Vuex.ts:
En cualquier función Componente para actualizar la tienda:
Ahora en cualquier componente para obtener la actualización:
fuente