LoginSignup
206
168

More than 5 years have passed since last update.

$watchでオブジェクトの変更を監視する方法

Posted at

はじめに

Vue.jsで生成したオブジェクトは$watchというメソッドを持っています。
これによりデータの変更を監視することが可能になります。
しかし、$watchメソッドは、オブジェクトの追加や削除を検出してくれますが、
オブジェクトの値が変更された場合は検出しません。😢

次のような例をみてください。
(※例ではVueインスタンスのwatchオプションに設定していますが、インスタンス化したときにオブジェクトの各エントリに対して$watchメソッドが呼び出されます)

<script>
  export default {
    data () {
      return {
        someObj: {
          a: 'obj-a',
          b: 'obj-b',
          c: 'obj-c'
        }
      }
    },
    watch: {
      someObj: function (val, oldVal) {
        console.log('someObj changed')
      }
    }
  }
</script>

この場合、オブジェクトデータsomeObjの中のネストされた値(someObj.a,someObj.b,someObj.c)が変更されても、
watchオプションでは検出してくれません💦
オブジェクトの変更を検出するには、以下の方法があります😇

オブジェクトを丸ごと監視したい場合(ネストしたデータも監視したい場合)

<script>
  export default {
    data () {
      return {
        someObj: {
          a: 'obj-a',
          b: 'obj-b',
          c: 'obj-c'
        }
      }
    },
    watch: {
      someObj: {
        handler: function (val, oldVal) {
          console.log('someObj changed')
        },
        deep: true
      }
    }
  }
</script>

options引数にdeep: trueを渡すことで、
オブジェクトの中のネストされた値の変更を検出することができます。
※監視する際のコールバック処理はhandlerに記述します。

オブジェクトを個々に監視したい場合

<script>
  export default {
    data () {
      return {
        someObj: {
          a: 'obj-a',
          b: 'obj-b',
          c: 'obj-c'
        }
      }
    },
    watch: {
      'someObj.a': function(val){
        console.log('someObj.a changed');
      },
      'someObj.b': function(val){
        console.log('someObj.b changed');
      },
      'someObj.c': function(val){
        console.log('someObj.c changed');
      }
    }
  }
</script>

watchのキーを'someObj.a'のようにクォーテーションで囲うことで、
それぞれのプロパティを個々に監視することができます。

まとめ

多くの場合では、データの変更を監視するには算出プロパティの方が適切だと思うのですが、
中にはカスタムウォッチャが必要な時もあると思います✌️
データの変更に対して反応する、watchオプションはとても汎用性が高く便利ですね😇

206
168
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
206
168