Ву.js - как правильно следить за вложенными данными


Я пытаюсь понять, как правильно следить за некоторыми вариациями опоры. У меня есть родительский компонент (.Vue files), которые получают данные из вызова ajax, помещают данные внутри объекта и используют его для визуализации некоторого дочернего компонента через директиву v-for, ниже упрощения моей реализации:

<template>
    <div>
        <player v-for="(item, key, index) in players"
            :item="item"
            :index="index"
            :key="key"">
        </player>
    </div>
</template>

... тогда внутри <script> теги:

 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]);
            }
    });
}

объекты item выглядят так:

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

теперь, внутри моего ребенка "игрок" компонент я пытаюсь следите за изменением свойств любого элемента, и я использую:

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

это работает, но это кажется немного сложным для меня, и я был интересно, если это правильный способ сделать это. Моя цель состоит в том, чтобы выполнять некоторые действия каждый раз prop изменения или myArray получает новые элементы или некоторые изменения внутри существующих. Любое предложение будет оценено.

3 142

3 ответа:

можно использовать глубокий наблюдатель для этого:

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

теперь это будет обнаруживать любые изменения объектов в item массив и дополнения к самому массиву (при использовании с Vue.набор). Вот JSFiddle:http://jsfiddle.net/je2rw3rs/

EDIT

если вы не хотите следить за каждым изменением на объекте верхнего уровня, а просто хотите менее неудобный синтаксис для просмотра вложенных объектов напрямую, вы можете просто посмотреть computed вместо:

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

вот JSFiddle:http://jsfiddle.net/oa07r5fw/

еще один хороший подход, и тот, который немного более элегантный, выглядит следующим образом:

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

(я узнал этот подход от @peerbolte в комментарий)

как, если вы хотите посмотреть свойство на некоторое время, а затем отменить его?

или посмотреть свойство дочернего компонента библиотеки?

вы можете использовать "динамический наблюдатель":

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

The $watch возвращает функцию unwatch, которая перестанет смотреть, если она вызвана.

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

также вы можете использовать :

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

пожалуйста, не забудьте взглянуть to документы