Ne:Code道場~watchの巻~


Ne:Code道場~watchの巻~

プログラミング学習で、漫画など視覚的なものと併用すると楽しく継続的に学んでゆける人も多いと思います。そこでこの連載では、猫の漫画を交えつつ、JavaScriptのフレームワーク、Vue.jsのwatchにおける学習ポイントについて紹介します。

目次
  1. はじめに
  2. watchって何ニャ
  3. watchの書き方や動きについて教えてニャ
  4. templateの部分について教えてほしいニャ
  5. 最後に

はじめに

image この記事ではVue.jsのwatchについて、概要について取り上げつつ、躓きポイント を補足しています。 各節ごとに、Ne:Code道場(猫de道場)の弟子猫がポイントをまとめ、最後に師匠猫がそれらを総括して3ポイントでまとめています。 それらのポイントを中心に、Vue.jsのwatchについて理解を深めてゆきましょう。
(いままでの記事もそうですが、Vue.jsはバージョンは2を用いています。サンプルコードで「vue@2.6.0」という部分でその指定を行っています。Vue.jsの最後で今まで取り上げたものとバージョン3での比較をまとめたいと思っています)

watchって何ニャ

前々回前回の記事では、2回にわたりVue.jsのcomputedを用いて、できることをみてゆきましたね。dataに定義されているものの値が変わると、その値と紐付いていたcomputedのものが連動して変わっているのを確認できました。computedでは連動して再計算されていましたが、watchでは、dataで定義されているものをwatch、監視して値が変わった時に処理を仕込んでゆくことが可能になります。まずは、簡単なVue.jsのコードを見るところから初めてゆきましょう。
最初にJavaScriptからです。

new Vue({
  el: "#app",
  data: {
    price: 0,
    // この後の2つは、watchの動作確認用に定義されたものらしいニャ
    newPrice: null,
    oldPrice: null
  },
  // ニャ!computedの時のようにwatchのエリアが定義されているニャ
  watch: {
    // ニャニャ?priceとニャ?dataのところで定義しているものと同じ記載ニャ。でもこっちは丸括弧がついているニャ!
    // 引数には、2つの値を受け取っているニャ。詳しくは記事の方を見るニャ
    price(newValue, oldValue) {
      // まずは動作確認としてのコードが書いてあるニャ~
      this.newPrice = newValue
      this.oldPrice = oldValue
    }
  }
});

まずは、動作確認用にまとめてみました。必要最低限のdataとwatchのみを記載しています。「watchとはなんぞや?」の動きを確認するためだけに、newPriceとoldPriceをdataに定義しています。watchには、priceという、dataに定義しているものと全く同じメソッドが定義されていますね。仔細は次の説明に譲るとして、そのpriceメソッドの中では、引数の値をそのまま動作確認用の変数(newPrice、oldPrice)に代入していることを確認できるでしょう。
次にHTML側を見てゆきます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>お試しHTMLニャ</title>
</head>
<body>
  <div id="app">
    <!-- ニャ!ここでバインドされているのは、dataの方で定義されているpriceニャ -->
    <input type="number" v-model="price">
    <!-- おニャ?なんだかtemplateというのが記載されているニャ?これの説明は記事を見るニャ~ -->
    <template v-if="newPrice !== null">
      <!-- 動作確認用にnewPriceとoldPriceの値を出力しているニャ -->
      <!-- 上のv-modelでバインドされたpriceをwatchした結果のnewPriceだから、ここの「ぶっちゃけ」は確かにニャ! -->
      <p>入力された値は:{{ newPrice }}ニャ <small>ぶっちゃけ、price({{ price }})と同じ値ニャ!</small> </p>
      <!-- 一つ前の値を見れるのは便利そうニャ♪ -->
      <p>入力される前の値は:{{ oldPrice }}ニャ! <small>古い値を確認できるニャ!</small></p>
    </template>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
  <script src="script.js"></script>
</body>
</html>

watch以外にも、templateとv-ifの重ね技の記載についても取り込んでいますが、仔細は後続節で補足しますね。画面初期表示時には、入力エリアしか存在していないですが、数値の値を変更してゆくと、入力した値と、その前に入力されていた値が、下の表示エリアに出力されてゆく動作を確認できるでしょう。watchはその名の通り、priceの値の変更を監視し、変更されるごとに実行されている様を確認できたかと思います。
では、段階を追って確認してゆきましょう。
image

watchの書き方や動きについて教えてニャ

watchは、その名前の通り、dataの値を「監視し、その変更時に処理を挟み込みたい」場合に用います。
computedの時同様、内部でdataの値にアクセスする際には、「this.newPrice」の様に、「this」が用いられていることを確認できますね。
computedでは好きなメソッド名を書けました。ですが、watchにおいては、どのdataの値を監視したいのかVue.jsに伝える必要があるため、メソッド名には、dataで定義されたものと一致する値が記載されているのですね。
なので、例えば以下のように記載すると正しく動作しません。

  // 変更箇所のみ抜粋ニャ!
  watch: {
    // メソッド名を動詞込の書き方に変えてみたニャ!
    // ・・・。う、動かなくなったニャ。。T目T
    changePrice(newValue, oldValue) {
      this.newPrice = newValue
      this.oldPrice = oldValue
    }
  }

先程まで動作していたものが、ちょっとの変更だけで動かなくなってしまったのを確認できたでしょう。ルールがあるものは、ルールに則ってはじめて正しく動作するというのがここでも当てはまるのですね。実際Vue.js側の気持ちになって考えてみると、これでは何をwatchしてよいのかわからない、という迷子感を味わえるかと思います。
次に引数についてです。
watchの場合は、引数2つを用いることがルールです。そして、その引数も「1つ目が新しい値」「2つ目が変更前の値」というルールで値が送り込まれてきます。引数の名前は自分で好きにつけることが可能ですが、よほどの理由がない限りは、1つ目には「newっぽい値」を、2つ目には「oldっぽい値」をつけるようにしましょう。
例えば、以下のように書いてあったら混乱の元ですよね。

  // 変更箇所のみ抜粋ニャ!
  watch: {
    // ルールに逸脱する名前をつけてしまったニャ。。
    // ・・・。わ、わかりにくいニャー!!T目T
    price(oldValue, newValue) {
      this.newPrice = oldValue
      this.oldPrice = newValue
    }
  }

トリッキーな書き方をしてはマズイというのを体感してもらえたかと思います。正直自分自身が数日後に見ても、「?」になること請け合いですし、他の人が見たら「(怒)」となってしまう可能性も出てきてしまうかもしれません。イディオムの様な記載の箇所は、それに則って記載しておいたほうが自分も他の人もハッピーになれるということですね。
最後に、以下のNGパターンも見ておきましょう。

  // 変更箇所のみ抜粋ニャ!
  watch: {
    // newとoldをつけるってことなら、もっと短くしてみるのはどうニャ?
    // ・・・。こ、これはエラーになってしまうニャ!!><
    price(new, old) {
      this.newPrice = new
      this.oldPrice = old
    }
  }

JavaScriptが使うことを予約しているキーワード、「予約語」の中に「new」は含まれているので、ここまで短く書くことは出来ないのですね。抽象度高めに書くならば最初の例の様に末尾にValueをつけて書けばOKです。具体的にそれぞれの値と紐付けて書くのであれば、この場合は、priceのwatchなので、「newPrice、oldPrice」などと書くと良いでしょう。
どちらであっても、1つ目に「最新の値」、2つ目に「古い値」が入ってくるというのが一目瞭然な名前をつけてあげると良いですね。
image

templateの部分について教えてほしいニャ

watchについての追加の補足は次回の記事に譲りつつ、ここでは最初のサンプルコードで記載していたtempate部分に関して補足します。

    <template v-if="newPrice !== null">
      <p>入力された値は:{{ newPrice }}ニャ <small>ぶっちゃけ、price({{ price }})と同じ値ニャ!</small> </p>
      <p>入力される前の値は:{{ oldPrice }}ニャ! <small>古い値を確認できるニャ!</small></p>
    </template>

v-ifを用いると、要素の表示非表示が可能になるというのは、以前の記事でも取り上げましたが、例えば上記の例のように、複数の要素をまとめて表示非表示したいというシーンもあると思います。その際に元々HTML側に親に当たる要素がいたら、その親要素にv-ifをつけてあげればよいのですが、今回の例ではその親要素がいません。
表示非表示の動作のためだけにHTMLの要素を追加しなくとも、対応できるのがこちらのtemplate部分の記載になります。最終的なHTMLにはこのtemplate自体はレンダリングされず、v-ifの条件に合致した際に、その中身のみが表示されるという動きになるのです。
image

Webサイト担当者としてのスキルが身に付く

無料カウンセリングはこちら

最後に

Vue.jsのwatchについて、猫弟子がいくつか上げたポイントを、猫師匠が厳選3ポイントでまとめたのがこちらです。

  1. dataの値の更新を監視し、更新されたタイミングで処理を挟むことができるのがwatchニャ
    1. computedは連動して計算結果を返す役割をしていたニャ。watchでは、計算結果を返すのではなく、連動して処理を挟んでゆくことが可能ニャ
  2. 監視してほしいdataの値でメソッド名を書くニャ
    1. それだけで監視をしてくれるという親切な作りニャ
    2. 引数は最初は新しい値(現在の値)、次は古い値(一つ前の値)が入ってくるニャ。わかりやすい引数名をつけておくニャ
  3. watchから外れるけれど、templateの便利な使い方について触れたニャ
    1. 「HTML側に余分な要素は起きたくないけど、まとめて、v-ifやv-forしたいニャ!」というシーンに活躍するニャ~

Vue.jsの11個目の記事として、Vue.jsのwatchについて学びました。
見た目のフレームワークとしてVue.jsを学ぶことで、JavaScriptとしてできることがぐっと高まってゆくと思います。
するとコードへの理解も深まり、プログラミングが更に楽しくなってくるでしょう。
Vue.js導入に関連する知識をしっかり身につけつつ、今後の学習に繋げてゆきましょう。
image


小泉七菜
この記事を書いた人
小泉七菜
まずは7日間お試し!人気プログラミング講座を無料公開中
オンライン・プログラミングレッスンNo.1のCodeCamp