jtk

【学習メモ】Vue.js のツボとコツがゼッタイにわかる本 その1

Vue.js のツボとコツがゼッタイにわかる本 という本を読んでいます。

Vue.jsのツボとコツがゼッタイにわかる本

Vue.jsのツボとコツがゼッタイにわかる本

Amazon でググってて把握したのですが、このシリーズって技術本に限らず簿記とか民法とかいろいろでているんですね。
イラストはカエルがでてくるので、カエル本?🐸 といえばいいでしょうか。

  • Vue.js の特徴
  • これまでバックエンド側が担った役割をフロントエンド側が担うようになった流れ
  • データバインディングとは
  • MVCモデル、MVVMモデルとは
  • オブジェクトの概念

的な話から第1〜2章で扱っていて、JavaScript にこれまで触れてこなかった層にもアプローチする内容が他の本とは違う点かなと思います。

難易度的にはタイトルから想像つく通り他のほんと比べても簡単な内容だと思います。順番してはこれまで読んだ本では難易度の高い順に、

  1. Vue.js入門 基礎から実践アプリケーション開発まで
  2. 基礎から学ぶ Vue.js(ネコ本)
  3. 動かして学ぶ!Vue.js 開発入門(イヌ本)
  4. Vue.js のツボとコツがゼッタイにわかる本(カエル本・この本)

となるのかなという印象です。

気になった箇所、覚えたい箇所をメモしていきます。

第2章 Vue.js をはじめよう!

2-4 レンダリング(ページを描画する)

リストデータをバインドする

<template>
  <table border="1">
    <tr>
      <th>商品コード</th>
      <th>商品名</th>
    </tr>
    <tr v-for="item in products" v-bind:key="item.code">
      <td>{{item.code}}</td>
      <td>{{item.name}}</td>
    </tr>
  </table>
</template>
export default {
  name: 'App',
  data () {
    return {
      products: [
        {
          code: 'A01',
          name: 'プロダクトA',
        },
        {
          code: 'B01',
          name: 'プロダクトB',
        },
        {
          code: 'C01',
          name: 'プロダクトC',
        }
      ]
    }
  }
}

一般的なループですが、これまで触ってきてはっきりしていなかった部分2つに解説がありました。

v-for の「配列要素を代入する変数名」は何でもよい

v-for の一つ目の変数(リスト6では item)には、繰り返しのたびに自動的に配列要素が代入されるので、変数名と同じ名前のプロパティをdataオプションに定義しておく必要はありませn。そのため、一つ目の変数名は何でもよいことになります。
一般的には、itemelementele のように、それが配列要素であることがわかる抽象的な変数名が使われることが多いようです。配列変数に複数形を表す s を付けている場合は、s を外した変数名を使ってもよいでしょう。例)v-for="product in products"

決まりがないことは知っていましたが、何でもよい、と言われると気がラクですね。

繰り返す要素にはキー(key)を指定しよう

例えば画面に削除ボタンがあって、1件目の商品データをユーザーが削除したとします。するとどうなるでしょうか?商品コード「A01」の行がDOMから削除されると予想されますが、実際の挙動は異なります。Vue.js は、「A01」のノードへ「B01」のデータを移し替え、「B01」のノードへ「C01」のデータを移し替えます。そして最後に「C01」のノードだけを削除します。つまり、効率的に描画するために、ノードの移動や削除を抑えて、なるべく使いまわそうとするのです。
その結果、バインドしている配列の要素番号(インデックス)とDOMノードがずれてしまい、配列要素の並び替えや追加を行ったとき正しく動作しない原因になります。
この問題を回避するために、v-for で繰り返す1つ1つの配列要素を区別できる値を、key という名前の属性を使ってバインドすることがVue.js公式ガイドで強く推奨されています。

これ「強く推奨」と書いてある通り、Vue.js の ES Lint を入れている場合 key がないとエラーになってしまうんですよね。

[vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives.eslint-plugin-vue

ググってなんとなく key をいれていたのですが、あまり理由を分かっておらずだったのでスッキリしました。

2-7 イベントハンドリング(ユーザーの操作を検知する)

<template>
  <div>
    <p>ウィンドウの横幅:{{width}}</p>
    <p>ウィンドウの高さ:{{height}}</p>
  </div>
</template>
export default {
  name: 'app',
  data () {
    return {
      width: window.innerWidth,
      height: window.innerHeight
    }
  },
  created: function() {
    // イベントハンドラを登録
    addEventListener('resize', this.resizeHandler);
  },
  beforeDestroy: function() {
    // イベントハンドラを削除
    removeEventListener('resize', this.resizeHandler);
  },
  methods: {
    // イベントハンドラ
    resizeHandler: function($event) {
      // 現在のウィンドウサイズでプロパティを更新
      this.width = $event.target.innerWidth;
      this.height = $event.target.innerHeight;
    }
  },
}

これも結構な勘違いだったのですが、こういうイベントごとの検知は名前からしてウォッチオプション(watch: {})を使うと思ってたのですが、Vue.js に頼らずともできるということなのですね。
その代わり Vue.js を介さずに登録したイベントハンドラは、不要になったタイミング(beforeDestroy ライフサイクルハックなど)で removeEventListener 関数を呼び出して解除する必要があるとのこと。

2-8 ウォッチャ(データの変更を監視する)

ウォッチャとは?

そしたらウォッチャとは何なのか?ということになりますが、ちゃんと説明されていました。

感覚的には 2-7節 のイベントハンドリングと似ていますが、ハンドラが呼び出されるタイミングがイベントではなくデータの変更である点が異なります。

要は、

  • イベントによる検知 => addEventListener('hogehoge'...) を使う
  • データの変更による検知 => watch: {} を使う

ということですね。

算出プロパティとウォッチャの使い分け

対象とするプロパティが返すデータを、アプリケーションに保持された他のデータの状態に応じて切り替えたい場合には、算出プロパティを使ってもよいでしょう。
しかし、返したいデータをアプロケーションの外部から取得しなければならない場合、算出プロパティではハンドラが処理を終えるまで再描画されないので、ユーザーを待たせてしまいます。ウォッチャなら、Ajax と呼ばれる非同期通信を使ってユーザーの待ち時間を軽減したり、ブラウザに重い負荷がかからないようにハンドラの実行頻度を調整したりできるので、より快適なインターフェースを提供できます。

computed: {}watch: {} かいつも迷うんですが、これで分かったような、分からないような。。
イメージ的に、computed でできることは watch でもできることで、できる限りは computed を使う、というイメージでいるのですが。。


基本的に内容のおさらいなので第2章までで気になった箇所はこのくらいで、ほかはこんなんあったなーと読みすすめていました。