【vue】 watchを使って値の変化時に自動で処理を実行する
監視プロパティとも呼ばれます。computed
と似ており、監視している値に変更があれば自動的に実行されるものです。
しかし、watch
ではcomputed
よりもロジックの処理に重点が置かれています。
watchを用いた例
次のような例を見てみましょう。
const app = Vue.createApp({ data() { return { shareId: "abcde", } }, computed: { shareUrl() { return "https://example.com/?id=" + this.shareId; } }, methods: { startShare() { this.shareId = "abcde"; this.sendShareData(); }, changeShareId() { // ランダム文字列を生成 this.shareId = Math.random().toString(32).substring(2); this.sendShareData(); }, stopShare() { this.shareId = ""; this.sendShareData(); }, sendShareData() { // サーバに新しいシェア情報を送信 // ... } } });
先程と似た例ですが、今度はデータを送信しているようです。中で値の代入などはするでしょうが、戻り値を使いたいということはなさそうです。
しかし、shareId
の変更がある場所全てにsendShareData
の呼び出しを付けるのは面倒ですし、保守性も下がります。
そこでwatch
です。watch
は指定した変数を監視して、変更があれば自動的に実行してくれるものです。
const app = Vue.createApp({ data() { return { shareId: "abcde", } }, computed: { shareUrl() { return "https://example.com/?id=" + this.shareId; } }, methods: { startShare() { this.shareId = "abcde"; }, changeShareId() { // ランダム文字列を生成 this.shareId = Math.random().toString(32).substring(2); }, stopShare() { this.shareId = ""; }, }, watch: { shareId(newVal, oldVal) { // サーバに新しいシェア情報を送信 // ... console.log(newVal) }, } });
最後の方にwatch
を追加しました。methods
と同様に複数設定できます。
watchの使い方
ここで、少し構造を見ていきましょう。

構造の特徴として、名前が監視したい対象であるという点です。更新後の値だけで十分な場合、第2引数は省略できます。何なら更新後に呼ばれるので、引数は無しにして直接this.shareId
などとしても良いです。
また、連想配列なので、次のように書くこともできます。
const app = Vue.createApp({ // ... watch: { shareId: function (newVal, oldVal) { // ... console.log(newVal) }, } });
これであれば、キー名に使えない文字列が含まれていても"share-id": function ()...
のようにかけますね。
オブジェクトの値を監視したい場合
"foo.bar.1"
のように、配列に近い感覚で書きますが、[]
ではなく.
で指定します。
const app = Vue.createApp({ data() { return { foo: { bar: [ 10, 20, 30 ] } } }, watch: { // ここ "foo.bar.1": function () { console.log(this.foo.bar[1]); }, } });
いつもの変数の扱いと似ていますが、注意点として、配列のインデックスも.
で指定します。[]
で指定しても動作しないので注意です。インデックスはいつもどおり0
から始まります。
また、オブジェクトや配列の中身が更新されたら、という条件にしたい場合は次のようにします。
{ // ... watch: { "foo.bar": { handler: function () { console.log(this.foo.bar[1]); }, deep: true, // オブジェクトの中まで監視する } } }
このように書くと、foo.bar[0]
、foo.bar[1]
、foo.bar[2]
どれに変更が入っても実行されます。
ちなみに、これまでに出した今までのwatch
の書き方は省略した書き方です。省略せずに書くと、
{ watch: { "監視対象": { handler: function () { // 実行したい処理 }, deep: false, // trueにすると、オブジェクトの中身全てが監視対象になる immediate: false // trueにすると、mountedより先に一度呼ばれる } } }
となります。
immediate
がtrue
の場合、beforeCreate
とcreated
の間に一度呼ばれます。これらはvueのライフサイクルで、mounted
はその後に呼ばれます。
動作例
最後に、実際に動いている例を見てみましょう。IDを更新ボタンを押して1秒待つと、更新完了と表示されるプログラムです。
See the Pen by Totori (@souki202) on CodePen.
URLはcomputed
で、1秒後に表示するのはwatch
で行っています。
まとめ
監視プロパティ(watch)は、特定の値が更新されたのをトリガーにして、何かの処理を行いたい際に最適です。戻り値は取らないので、戻り値が必要な場合はmethod
かcomputed
を推奨します。
似ているcomputed
に関しては下の記事にあります。
method
, computed
, watch
の使い分けは下の記事にあります。
