Vue - オブジェクトの配列を深く監視し、変更を計算しますか? 質問する

Vue - オブジェクトの配列を深く監視し、変更を計算しますか? 質問する

people次のようなオブジェクトを含む という配列があります。

前に

[
  {id: 0, name: 'Bob', age: 27},
  {id: 1, name: 'Frank', age: 32},
  {id: 2, name: 'Joe', age: 38}
]

変更される可能性があります:

[
  {id: 0, name: 'Bob', age: 27},
  {id: 1, name: 'Frank', age: 33},
  {id: 2, name: 'Joe', age: 38}
]

フランクはちょうど33歳になったことに注目してください。

私は、people 配列を監視し、いずれかの値が変更されたときにその変更をログに記録するアプリを持っています。

<style>
input {
  display: block;
}
</style>

<div id="app">
  <input type="text" v-for="(person, index) in people" v-model="people[index].age" />
</div>

<script>
new Vue({
  el: '#app',
  data: {
    people: [
      {id: 0, name: 'Bob', age: 27},
      {id: 1, name: 'Frank', age: 32},
      {id: 2, name: 'Joe', age: 38}
    ]
  },
  watch: {
    people: {
      handler: function (val, oldVal) {
        // Return the object that changed
        var changed = val.filter( function( p, idx ) {
          return Object.keys(p).some( function( prop ) {
            return p[prop] !== oldVal[idx][prop];
          })
        })
        // Log it
        console.log(changed)
      },
      deep: true
    }
  }
})
</script>

私はこれに基づいて昨日私が尋ねた質問配列の比較について質問し、最も早く機能する回答を選択しました。

したがって、この時点で次のような結果が期待されます。{ id: 1, name: 'Frank', age: 33 }

しかし、コンソールに返されるのは次の内容だけです (コンポーネント内にあることを念頭に置いてください)。

[Vue warn]: Error in watcher "people" 
(found in anonymous component - use the "name" option for better debugging messages.)

そして、私が作ったコードペン結果は空の配列となり、変更されたオブジェクトは期待どおりに生成されません。

なぜこのようなことが起こるのか、または私がどこで間違えたのかを誰か教えていただければ、大変助かります。どうもありがとうございます!

ベストアンサー1

古い値と新しい値の比較関数に問題があります。後でデバッグの手間が増えるので、あまり複雑にしない方がよいでしょう。シンプルにしておくべきです。

最善の方法は、 を作成しperson-component、以下に示すように、独自のコンポーネント内で各人物を個別に監視することです。

<person-component :person="person" v-for="person in people"></person-component>

以下に、person コンポーネント内の監視の実例を示します。親側で処理する場合は、変更された person を$emit含むイベントを上向きに送信するために を使用できますid

Vue.component('person-component', {
    props: ["person"],
    template: `
        <div class="person">
            {{person.name}}
            <input type='text' v-model='person.age'/>
        </div>`,
    watch: {
        person: {
            handler: function(newValue) {
                console.log("Person with ID:" + newValue.id + " modified")
                console.log("New age: " + newValue.age)
            },
            deep: true
        }
    }
});

new Vue({
    el: '#app',
    data: {
        people: [
          {id: 0, name: 'Bob', age: 27},
          {id: 1, name: 'Frank', age: 32},
          {id: 2, name: 'Joe', age: 38}
        ]
    }
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<body>
    <div id="app">
        <p>List of people:</p>
        <person-component :person="person" v-for="person in people"></person-component>
    </div>
</body>

おすすめ記事