web-dev-qa-db-ja.com

Vue.js - 入れ子になったデータを正しく監視する方法

プロップのバリエーションを正しく監視する方法を理解しようとしています。私はajax呼び出しからデータを受け取る親コンポーネント(.vueファイル)を持っていて、そのデータをオブジェクトの中に置き、それを使って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:{
   prop: value,
   someOtherProp: {
       nestedProp: nestedValue,
       myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
    },
}

さて、私の子の "player"コンポーネントの中で、私はItemのプロパティの変化を監視しようとしています、そして私は以下を使います:

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

それはうまくいきますが、それは私にとって少しトリッキーに思えます、そして、これがそれをする正しい方法であるかどうか私は思っていました。私の目標は、propが変更されたりmyArrayが新しい要素や既存の要素の中に何らかのバリエーションを取得するたびに何らかのアクションを実行することです。任意の提案は大歓迎です。

235
Plastic

ディープウォッチャー を使うことができます。

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

これにより、item配列内のオブジェクトへの変更および配列自体への追加が検出されます( Vue.set と共に使用した場合)。これがJSFiddleです: http://jsfiddle.net/je2rw3rs/ /

_編集_

最上位オブジェクトのすべての変更を監視する必要がなく、ネストされたオブジェクトを直接監視するための厄介な構文を使用したくない場合は、代わりに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/ /

369
craig_h

もう1つの良い方法ともう少しエレガントな方法は次のとおりです。

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

(私はこのアプローチを@peerbolteから コメントはこちら で学んだ)

261
Ron C

別の方法.

矢印機能 を使わないでください。 this オブジェクトにアクセスすることはできません。

watch:{
    'item.someOtherProp': function(newValue, oldValue){
        // Process
    }
}
4
Yasin UYSAL

不動産をしばらく見てから見たくない場合はどうしますか。

またはライブラリの子コンポーネントのプロパティを見るには

あなたは "動的ウォッチャー"を使うことができます:

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

$watchはunwatch関数を返します。この関数が呼び出されると監視を停止します。

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

deepオプションも使えます。

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

必ず を見てください

4
roli roli

ここでは言及していませんが、Vueクラスを拡張する場合は、vue-property-decoratorパターンを使用することもできます。

import { Watch, Vue } from 'vue-property-decorator';

export default class SomeClass extends Vue {
   ...

   @Watch('item.someOtherProp')
   someOtherPropChange(newVal, oldVal) {
      // do something
   }

   ...
}
2
getglad

deep: trueを使用するという受け入れられた答えに関する私の問題は、配列を深く見ているときに、 which 要素を簡単に識別できないことです。私が見つけた唯一の明確な解決策は この答えです。これは、各配列要素を個別に見ることができるようにコンポーネントを作成する方法を説明しています。

1
krubo

このソリューションを「ハッキング」するために使用した別の方法は、これを行うことでした。ネストされたオブジェクト値を返すだけの別のcomputed値を設定しました。

data : function(){
    return {
        my_object : {
            my_deep_object : {
                my_value : "hello world";
            }.
        },
    };
},
computed : {
    helper_name : function(){
        return this.my_object.my_deep_object.my_value;
    },
},
watch : {
    helper_name : function(newVal, oldVal){
        // do this...
    }
}
1
Zac

子オブジェクトのVueJsの詳細監視

new Vue({
    el: "#myElement",
    data: {
        entity: {
            properties: []
        }
    },
    watch: {
        'entity.properties': {
            handler: function (after, before) {
                // Changes detected. Do work...     
            },
            deep: true
        }
    }
});
0
Alper Ebicoglu