ravelll の日記

よしなに

Vue.js やってる

来年、まずは Vue.js を利用しているプロジェクトに参加することになりそうなので https://jp.vuejs.org/v2/guide を見て書いてあることを自分なりにまとめなおしたりコード書いたりして勉強していた。
"基本的な使い方" だけ抑えて、後は必要になったとき探せばいいかなと思っている。ひとまず算出プロパティとウォッチャのパートまで。

以下は学習時のまとめです。

Vue インスタンス、オプションオブジェクト

ライフサイクル

  • Vue インスタンスは生成時に一連の初期化を行う
  • それらの各初期化段階ごとにユーザーのコードを追加するための関数(ライフサイクルフック)が実行される
    • create, mount, update, destroy それぞれの前後にある(beforeCreate, created ...)
    • 全てのライフサイクルフックにおける this は Vue インスタンスを指す
  • https://jp.vuejs.org/v2/guide/instance.html の最下部にライフサイクルの全体図がある

テンプレート

  • テンプレートは内部で VirtualDOM の描画関数にコンパイルされる
    • アプリケーションの状態が変わったら最低限の DOM 操作を行う
  • テンプレートを使わず render 関数で直接描画することもできる
  • データバインディングMustache の記法を使うのが基本
    • Mustache で展開した場合、データは HTML ではなくプレーンなテキストとして扱われる
    • HTML で展開する場合は v-html ディレクティブを使う
      • v-html は XSS の温床なのでユーザからのコンテンツに対して使わない
  • Mustache は HTML の属性の内部では使えないので、その場合は v-bind ディレクティブを使う
    • <div v-bind:disabled="divDisabled">DIV</div> として divDisabled プロパティに値を入れる
  • Mustache の内部では js の式を書ける
    • 文は書けない(1 + 2 は OK、let num = 3 は NG)

ディレクティブ

  • v- から始まる Vue における特別な属性
  • v-for を除くディレクティブは属性値として単一の js 式を期待する
  • 属性値が変化すると各ディレクティブは副作用を DOM に適用する
  • v-bind:title における title は v-bind ディレクティブの引数
  • v-bind と v-on には省略記法がある
    • v-bind:title -> :title
    • v-on:click -> @click

算出プロパティ

  • オプションオブジェクトに computed プロパティとして指定
  • 例えば upperTitle 算出プロパティを定義すると vm.upperTitle の getter として使われる
    • 算出プロパティに渡すオブジェクトに set / get プロパティを書くことで setter も書ける
  • 同じ関数を methods プロパティで定義したときと computed プロパティで定義したときの差について
    • 結果は同じ
    • methods では再描画のたびに関数が評価される
    • computed では依存関係が更新されたときにだけ再評価され、それ以外はキャッシュされている評価結果を返す
    • 以下のようなコードを用意してブラウザのコンソールから vm.title を更新するときの振る舞いを見ると分かりやすい
<!DOCTYPE html>
<html>
  <body>
    <div id="app">
      <h1>
        {{ title }}
      </h1>
      {{ methods_now() }}
      {{ computed_now }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="./index.js"></script>
  </body>
</html>
const vm = new Vue({
  el: '#app',
  data: {
    title: "Sample Title"
  },
  methods: {
    methods_now: function () {
      return Date.now()
    }
  },
  computed: {
    computed_now: function () {
      return Date.now()
    }
  }
})
  • 監視(watched)プロパティもあるけど computed でできないか考えて使う
    • watch はデータ変更のたびに重い処理を非同期で行いたいときとかに便利

その他 Tips

  • インスタンスプロパティやコールバックでアロー関数は使わない
    • 親コンテキストに束縛されるため this が Vue インスタンスを指さなくなる