Vue.js - Cómo observar correctamente los datos anidados


Estoy tratando de entender cómo mirar correctamente para alguna variación prop. Tengo un componente padre (.archivos vue) que reciben datos de una llamada ajax, ponen los datos dentro de un objeto y los usan para renderizar algún componente hijo 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 <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 Item son así:

item:{
   prop: value,
   someOtherProp: {
       nestedProp: nestedValue,
       myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
    },
}

Ahora, dentro de mi componente hijo "jugador" estoy tratando de ver la propiedad de cualquier Elemento variación 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 o myArray recibe nuevos elementos o alguna variación dentro de los existentes. Cualquier sugerencia será apreciada.

Author: Webnet, 2017-02-09

3 answers

Puedes usar un deep watcher para eso:

watch: {
  item: {
     handler(val){
       // do stuff
     },
     deep: true
  }
}

Esto ahora detectará cualquier cambio en los objetos en la matriz item y adiciones a la matriz en sí (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 lugar:

var vm = new Vue({
  el: '#app',
  computed: {
    foo() {
      return this.item.foo;
    }
  },
  watch: {
    foo() {
      console.log('Foo Changed!');
    }
  },
  data: {
    item: {
      foo: 'foo'
    }
  }
})

Aquí está el JSFiddle: http://jsfiddle.net/oa07r5fw/

 238
Author: craig_h,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-14 16:37:51

Otro buen enfoque y uno que es un poco más elegante es el siguiente:

 watch:{
     'item.someOtherProp': function (newVal, oldVal){
         //to work with changes in someOtherProp
     },
     'item.prop': function(newVal, oldVal){
         //to work with changes in prop
     }
 }

(Aprendí este enfoque de @peerbolte en el comentario aquí )

 161
Author: Ron C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-01 13:29:53

¿Cómo si desea ver una propiedad por un tiempo y luego des-verlo?

O para ver una propiedad de componente hijo de biblioteca?

Puede utilizar el "observador dinámico":

this.$watch(
 'object.property', //what you want to watch
 (newVal, oldVal) => {
    //execute your code here
 }
)

El $watch devuelve una función unwatch que dejará de ver si se llama.

var unwatch = vm.$watch('a', cb)
// later, teardown the watcher
unwatch()

También puedes usar la opción deep:

this.$watch(
'someObject', () => {
    //execute your code here
},
{ deep: true }
)

Por Favor, asegúrese de echar un vistazo a google docs

 1
Author: roli roli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-07 18:03:02