プログラミング技術

本サイトはプロモーションが含まれています。

Vue/Nuxt.jsでwatchが動かないのはhandler, deepを使っていない?

watch[handler,deep]
初心者さん
Vue/Nuxt.jsでwatchがうまく動いてくれなくて監視できない。なぜだろう?

この記事はVue/Nuxt.jsでこのような状況になった人に向けて書いています。

結論から言うと、オブジェクトには【handler, deep】を使わなければ変更を監視できません。

▼この記事では以下の点を理解できます。

  1. watchの基本的な使い方
  2. watchが動かない時に確認する

Vue/Nuxt.jsを学習していて、watchが動かない時にぜひ、確認してみてください。

Vue/Nuxt.jsのwatchの基本的な使い方

watchの基本的な使い方を紹介します。最初は書き方が間違っていないか確認しましょう。

変数の変更を監視する場合

以下のサンプルコードはdataにcar_nameという変数を持っています。その変数の変更を監視してみます。

<template>
  <div>
    <button @click="changeCar()">車の買い替え</button>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      car_name: 'ステップワゴン'
    }
  },
  watch: {
    car_name() {
      this.writeConsole()
    }
  },
  methods: {
    changeCar() {
      console.log('----change')
      this.car_name = 'フィット'
    },
    writeConsole() {
      console.log('変更を監視')
      console.log(this.car_name)
    }
  }
}
</script>
  • STEP
    車の買い替えのボタンをクリック
    changeCar()というメソッドが呼ばれ、this.car_nameが「ステップワゴン」から「フィット」に変更される
  • STEP2
    car_nameの変更を監視
    dataのcar_nameをwatchで監視することで変更された後にwriteConsole()が呼ばれる

変数の監視の結果

watch-変数

【動かない例】オブジェクトが変更を監視する場合

オブジェクトの場合は階層が深くなります。変数の変更を監視する時と同じように書くと動きません。以下は動かない例

car: {
  car_name: 'ステップワゴン',
  maker: 'HONDA',
  color: 'blue'
}
<template>
  <div>
    <button @click="changeCar()">車の買い替え</button>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      car: {
        car_name: 'ステップワゴン',
        maker: 'HONDA',
        color: 'blue'
      }
    }
  },
  watch: {
    car() {
      this.writeConsole()
    }
  },
  methods: {
    changeCar() {
      console.log('----change')
      this.car.car_name = 'フィット'
    },
    writeConsole() {
      console.log('変更されました。')
      console.log(this.car)
    }
  }
}
</script>

watchが動かない

changeCar()までは呼ばれていますが、this.car.car_nameが変更してもwatchが変更を検知してくれてません。

watchが動かない例

【動く例】オブジェクトが変更を監視する場合

オブジェクトの場合は、【handler, deep】を使う必要があります。

<template>
  <div>
    <button @click="changeCar()">色を変えるボタン</button>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      car: {
        car_name: 'ステップワゴン',
        maker: 'HONDA',
        color: 'blue'
      }
    }
  },
  watch: {
    car: {
      handler() {
        this.writeConsole()
      },
      deep: true,
    }
  },
  methods: {
    changeCar() {
      console.log('----change')
      this.car.car_name = 'フィット'
    },
    writeConsole() {
      console.log('変更されました。')
      console.log(this.car)
    }
  }
}
</script>

オブジェクトで監視できている結果

writeConsole()まで来ているので、しっかり監視できています。【handler, deep】を忘れずに。どちらかがないと動かないので注意。

オブジェクトの監視

最初に画面を呼び出した場合にwatchを動かす【immediate】

最初に画面を呼び出した時にwatchを動かしたい場合ありますね。その時は【immediate】を使うと、実行されます。

この場合は、画面を呼び出した時にwatchが呼ばれるため、writeConsole()が実行されるだけです。

<template>
  <div>
    <button @click="changeCar()">色を変えるボタン</button>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      car: {
        car_name: 'ステップワゴン',
        maker: 'HONDA',
        color: 'blue'
      }
    }
  },
  watch: {
    car: {
      handler() {
        this.writeConsole()
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    changeCar() {
      console.log('----change')
      this.car.car_name = 'フィット'
    },
    writeConsole() {
      console.log('変更されました。')
      console.log(this.car)
    }
  }
}
</script>

Vue/Nuxt.jsのwatchとcomputedどちらを使うか悩む時

どちらも変更を検知できるプロパティなのでどちらを使うか迷うこともあるかと思います。基本的にcomputedを使いますが、以下のときはwatchを使うといいです。

変更を検知して非同期処理をしたい場合は、watchを使う。

データが変わるのに応じて非同期やコストの高い処理を実行したいときに最も便利です。
引用元: Vue.js公式

APIを叩いて戻ったデータを使いたいといった場合は、watchを使います。

Vue/Nuxt.jsのwatchで【handler, deep】を使うまとめ

今回は、Vue/Nuxt.jsでwatchを使う方法を紹介しています。

オブジェクトの場合はhandler, deepを使うのを忘れると、変更を検知できないので忘れずに。動作しなくてもエラーはでないため注意しましょう。

▼以下の手順でプログラミングの学習してみてください。

-プログラミング技術