ユーニックス総合研究所

  • home
  • archives
  • vue-watch

Vueのwatchの革命的な使い方【JavaScript】

  • 作成日: 2020-12-01
  • 更新日: 2023-12-24
  • カテゴリ: Vue

Vueのwatchの使い方

JavaScriptのフロントエンド・ライブラリに「Vue(ビュー)」があります。
これは中国製のフロントエンド・ライブラリで世界中で使われている人気があるものです。

Vueを使うとリアルタイムなユーザーインターフェースを簡単に作成することが出来ます。

そのVueの中の機能に「watch(ウォッチ)」と言われる機能があります。
これを使うと、Vueの中で変数の変更を検知することが可能です。

この記事ではこのwatchの使い方を解説します。
具体的には↓を見ていきます。

  • watchの必要性とは?
  • Vueのプロジェクトの作成
  • watchの導入
  • watchの注意点

ではまずはwatchの必要性から考えてみましょう。

🦝 < watchは必要なのか?

watchの必要性とは?

watchの必要性について考えます。
どんな時にwatchは必要になり、使われるのでしょうか?

Vueを使ったプロジェクトを作成していると、変数が無数に作成されます。
これはdataプロパティの中に定義されたり、あるいはpropsプロパティに外部から渡されたりするものです。
それらの変数の管理はけっこう大変なものです。

特に「変数の値が変更された」などのイベントを検知しようとしてプログラミングすると、その労力は大きなものになります。
セッターやゲッターに関数を仕込んで変数の変更を検知しようとしたり、setTimeout()setInterval()で定期的に変数を監視したり……。

🦊 < めんどくさいですね

これらの労力を減らせると私たちの開発がはかどることになります。
Vueではこの労力を減らす仕組みとしてwatchがあります。

watchは、変数の変更を監視します。
変数の変更とは、変数の値の変化ということです。
watchは変数の値の変更を監視して、値が変更されたら設定された関数を呼び出します。

関数を呼び出すさいに、変更された変数の値を関数の引数に渡します。
こうすることで開発者は関数の呼び出しのときに、変更された変数の値も一緒に取得することが出来ます。
まさにwatchを使うというのはVueを使ったプログラミングにおいて革命的なことと言えます。
この便利さに慣れたらもうsetInterval()で変数を監視するなんてことしてられませんよね。

🐭 < setInterval()は良い子

Vueのプロジェクトの作成

では解説のためのVueのプロジェクトを作成したいと思います。
プロジェクトと言っても、HTMLファイルを1つだけです。
Vueはこれぐらいのコンパクトな開発にも対応しています。

index.htmlファイルを作成します。
このファイルの中身は↓のようなものです。

<!DOCTYPE html>  
<html>  
<head>  
  <title>Watch test</title>  
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>  
</head>  
<body>  
<div id="app"></div>  
<script>  
new Vue({  
  el: '#app',  
  data: {  
    message: 'Hello, World!',  
  },  
  template: `  
    <div>  
      <h1>{{ message }}</h1>  
      <button @click="message = message.toLowerCase()">Change!</button>  
    </div>  
  `  
})  
</script>  
</body>  
</html>  

↑のindex.htmlをブラウザで表示すると↓のような表示になります。

↑のプロジェクトの内容を解説します。
まずHTMLの中でVueのスクリプトをCDNから読み込んでいます。

  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>  

これでVueを使えるようになります。
それからアプリケーションの展開先のdiv要素を作っておきます。

<div id="app"></div>  

↑のdiv要素にVueのアプリを展開します。
それからVueクラスをインスタンスにして、さきほどのdiv要素に展開します。

new Vue({  
  el: '#app',  
  ...  
 })  

dataプロパティにmessage変数を作っておきます。
この変数の値をボタンで変更します。

  data: {  
    message: 'Hello, World!',  
  },  

templateにはmessageの表示と、messageの文字列を小文字にするボタンを置きます。

  template: `  
    <div>  
      <h1>{{ message }}</h1>  
      <button @click="message = message.toLowerCase()">Change!</button>  
    </div>  
  `  

あとはブラウザで表示し「Change!」ボタンを押せばmessageの表示が小文字になるという単純なスクリプトです。
それではこのプロジェクトにwatchを導入してみましょう。

watchの導入

さきほどのプロジェクトにwatchを導入します。
今回のwatchの目的は「Change!」ボタンが押されてmessage変数の内容が変わったときに、その値の変化を検知することです。
つまり「Hello, World!」というmessageの文字列が「hello, world!」という小文字の文字列になるところの変化を検出するというものです。

watchの導入には、まず最初にwatchプロパティを作ります。
そしてwatchプロパティに変数とその変数の変換を検出する関数を設定します。
変数の変化を検出したらalert()で変数の内容を表示します。

では最初にwatchプロパティを作ってみましょう。

watchプロパティの作成

watchプロパティの作成先はdataプロパティやtemplateプロパティと同じレイヤーになります。
今回はdataプロパティのとなりにwatchプロパティを作ります。

new Vue({  
  el: '#app',  
  data: {  
    message: 'Hello, World!',  
  },  

  // ↓ここにwatchプロパティを作る  
  watch: {  
  },  

  ...  
})  

watchプロパティの中身はただのオブジェクトです。
波カッコ({})でプロパティの中身を作っておきます。

watchする変数の設定

次にwatchプロパティの中に変数とそれに対応する関数を設定します。
今回はdataプロパティにあるmessage変数を監視したいわけですが、その場合は↓のように設定します。

  watch: {  
    message: function (val, oldVal) {  
      alert(val)  
    },  
  },  

↑のようにmessageプロパティにfunctionで関数を設定します。
関数の引数valには変更後のmessage変数の値が渡されるので、↑のように関数の引数を作っておきます。
それから引数oldValには変更前のmessage変数の値が渡されます。
関数の内容的にはalert()で引数valを表示しているだけです。

この変数と関数の設定方法にはいろいろなバリエーションがあります。
たとえば↓のような省略記法でも同じような動作が得られます。

  watch: {  
    message (val, oldVal) {  
      alert(val)  
    },  
  },  

それから変数名を文字列にすることも可能です。

  watch: {  
    'message' (val, oldVal) {  
      alert(val)  
    },  
  },  

文字列が必要になるケースですが、たとえばdataプロパティ内に作ってある変数が、オブジェクトの入れ子になっている場合などに使います。
↓のような場合です。

  data: {  
    form: {  
      content: 'Hello, World!',  
    },  
  },  
  watch: {  
    'form.content' (val, oldVal) {  
      alert(val)  
    },  
  },  

オブジェクトを丸ごと監視する

個々の変数ではなくオブジェクトを丸ごと監視したい場合は↓のようにします。

  data: {  
    form: {  
      name: 'Taro',  
      content: 'Hello, World!',  
    },  
  },  
  watch: {  
    form: {  
      handler (val, oldVal) {  
        alert(val.name + ' ' + val.content)  
      },  
      deep: true,  
    }  
  },  

↑のようにwatchプロパティ内に監視したいオブジェクトを指定します。
その中にhandler()という関数を作ります。
handler()には変更後の値valと変更前の値oldValが渡されます。
さらにdeepプロパティをtrueにしておきます。こうすることでオブジェクトの丸ごとの監視が有効になります。

watchの動作を見る

では「Change!」ボタンをクリックしてwatchの動作をテストしてみます。
message変数を監視してますが、↓のように表示されます。

message変数の変更後の値がalert()で表示されているのがわかります。

watchの注意点

便利なwatchですが、注意点があります。
それは↓のようなことです。

  • 使いすぎると意図しない動作になりやすい

watchの変数の監視は強力なものですが、なんでもかんでもこれで監視してしまうと、ありとあらゆる変数が監視されることになります。
そうすると意図しない動作になったり、バグの温床になったりします。
特に複雑なアプリケーションでは慎重に使うようにしましょう。

console.log()watchの動作、つまりwatchの呼び出し数を監視すると「え? こんなに呼ばれてるの?」なんてことがよくあります。
これがAjaxなどのHTTP通信を使っていたらと思うと、なかなかその怖さがわかると思います。
時間のかかるリクエストを何度も送ることになって、結果的にアプリケーションの動作が遅くなってしまうこともあります。

watchはその動作の把握がけっこうむずかしいので、使うさいはよく考えて使うようにしてください。

おわりに

今回はVueのwatchの使い方を解説しました。
Vueには便利な機能がたくさんあり、watchはその中でも強力なものです。
この記事が参考になれば幸いです。

🦝 < 己がVueを見つめるとき、またVueも己を見つめている