「基礎から学ぶVue.js」の感想・備忘録1

スポンサーリンク

書籍「基礎から学ぶVue.js」のまとめ。

点数

93

感想

いい本だった。
とてもわかりやすく説明されている。

まとめ

ディレクティブ

  • v-for
    <li v-for="item in items">{{ item }}</li>
  • v-on (.preventや.stop)
    <button v-on:click="handleClick">登録</button>
    ⇒省略記法<button @click="handleClick">
  • v-model (.numberや.trim)
    <input v-model="msg">
  • v-if
    <p v-if="show">Hello</p>
  • v-bind
    属性へのバインドはMustacheではなくv-bindディレクティブ
    <input v-bind:value="message">
    ⇒省略記法<input :value="message">
    ※class, styleはオブジェクトが展開される
    <p v-bind:class="classObject">Text</p>

その他

  • Chrome拡張機能のVue DevToolsをインストールするべき
  • 開発環境はvew.jsで本番環境はvew.min.jsを使う
  • ライフサイクルフックはcreated(DOM構築前)とmounted(DOM構築後)がよく使われる

知識

エディタ

Visual Studio Codeがおすすめ。
Vue.js用の拡張機能が提供されている。

JavaScriptライブラリ

  • Lodash
    ユーティリティライブラリ
  • axios
    Ajax用ライブラリ

Vue DevTools

Chrome拡張機能。
必ずインストールするべき。

STUDIO

Vue.jsで作られたデザインツール。
ウェブサイト自体もVue.jsをベースにしたNuxt.jsというフレームワークで構築されている。
https://studio.design/ja

ディレクティブ

v-で始まる属性は「ディレクティブ」と呼ばれ、データバインディングのために使用される。ディレクティブの値はJavaScriptの変数または式である。
(v-modelは変数のみ指定可)
例) <input v-bind:value="100+99">

コンポーネント

コンポーネントはhtmlとjsのセット。
単一ファイルコンポーネントはさらにCSSもセットにできる。

ネット上のコンポーネント集

  • Awesome Vue Github
  • Vue Curated
  • Element
    スライダー、日付ピッカー、ドラッグ対応ファイルアップローダ、など
  • Onsen UI
    モバイルアプリ用コンポーネント集

開発モード

非圧縮のvue.js本体は開発モードとなり、開発モードであることを示すメッセージがコンソールログに表示される。

基本

バインディングされた変数へのアクセス

Vueインスタンス.変数名

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
console.log(app.message);

ライフサイクルフック

  • created
    Vueインスタンスが作成され、データ監視などリアクティブまわりの初期化が終わった後。DOMはまだ構築されていない。thisへはアクセスできるがthis.$elやgetElementById()などによりDOMアクセスはできない。
  • mounted
    DOM作成直後。this.$elやgetElementById()が使用できる。

new Vue()は1回だけ実行するべき

Vueインスタンスは複数作成可能だが、操作したいすべての部分を包含している要素に1つだけnew Vue()を行い、そこにコンポーネントとしてUI部品を追加していくことで連携や再利用がしやすくなる。

dataオプションに定義した変数は後から追加できない

内容が決まっていない場合でも初期値を定義しておく。

data {
  todoText: '',
  visitCount: 0,
  todos: [],
  error: null
}

Mustacheは属性値には使用できない

属性へのバインドにはv-bindディレクティブを使用する。
<input type="text" value="{{ message }}" />とは書けない。
<input type="text" v-bind:value="message" />とする。

全データの確認

<pre>{{ $data }}</pre>

メソッドの短縮記法

hoge: function(){}は短縮記法でhoge(){}と書ける。
※ES2015の新仕様

classとstyleのバインディング

classとstyleは特別で、オブジェクトや配列をバインドするとクラス名やCSSプロパティとして展開される。
※クラスの場合は、キーがクラス名、値がブール値
※クラス名にハイフンが含まれる場合はシングルクォーテーションで囲む
※スタイルのプロパティはキャメルケースで記述する

<p v-bind:class="{child: true, 'is-active': isActive}">Text</p>
<p v-bind:style="{color: textColor, backgroundColor: bgColor}">Text</p>
<!-- または、オブジェクトを定義しておいて -->
<p v-bind:class="classObject">Text</p>
<p v-bind:style="styleObject">Text</p>

複数属性のバインディング

v-bindディレクティブの引数を省略してオブジェクトを渡すと、一括バインドができる。

<img v-bind="item">
<!-- とすれば -->
<img v-bind:src="item.src" v-bind:alt="item.alt" v-bind:width="item.width" v-bind:height="item.height">
<!-- のように書かなくてすむ。 -->

v-ifとv-show

v-ifがfalseの場合、DOMが削除される。(<!—->だけになる)
v-showがfalseの場合、CSSのdisplay: noneとなる

切り替え頻度が高いものはv-showを使用するとパフォーマンスがよくなる。

templateタグ

複数要素の表示/非表示を切り替えたい場合、divのようなブロック要素にv-ifを付与する。

または非表示ラッパーとして提供されているtemplateタグを使って複数要素をグループ化する。描画される結果にtemplate要素は含まれない。
※v-showでは使用できない

<template v-if="viewFlg">
  <header>タイトル</header>
  <div>コンテンツ</div>
</template>

v-else-if, v-else

v-ifディレクティブはv-else-if, v-elseディレクティブを指定できる。
※v-showでは使用できない

<div v-if="counter === 0">ゼロ</div>
<div v-else-if="counter < 10">一桁</div>
<div v-else>2桁以上</div>

key属性による再利用可能な要素の制御

v-ifで表示を切り替えたとき、同じ要素があると入力値が引き継がれることがある。key属性を付けることで回避できる。

<template v-if="loginType === 'username'">
  <input placeholder="Enter your username" key="username"></template>
<template v-else>
  <input placeholder="Enter your email address" key="address">
</template>
<!--key属性を付けないと、切り替えてもinputの入力値が残ることがある。-->

v-for

ユニークなkey属性を指定しなければならない。
リストの順番が入れ替わったりしたときに、変更前と変更後でキーが同じ要素は同じものだとみなされてDOM要素の移動が起こる。keyを指定しないとDOM要素の移動は起こらず、テキストのみが変更されてしまう。

なお、keyに配列のインデックスを使用してはいけない。(sortや要素削除で参照するテキストが変わってしまうため)
プライマリーキーなどユニークなものを指定する。

<ul>
<li v-for="item in list" v-bind:key="item.id">{{ item.name }}</li>
</ul>
  • v-for="(item, index) in list"でインデックスも受け取れる
  • v-for="(item, key) in list"でハッシュのキーも受け取れる

変数の更新が検出されないケース

  • インデックスを使った配列要素の更新(配列操作は配列メソッドを必ず使う)
  • 後から追加された変数の更新
data: {
  list: [33,44]
}
// としてメソッド内で
this.list[1] = 100; // 更新が検出されない
this.hoge = 100; // 更新が検出されない
// ※Vue.setメソッドを使う必要がある

Vue.setメソッド

インデックスでの配列要素の更新、プロパティの新規追加、をリアクティブデータとして扱えるようにする。
エイリアスはthis.$set
this.$set(配列orオブジェクト, インデックスorキー, 値);

this.$set(this.list, 3, 'abc');

元の配列を変更しないメソッドfilter, concat, slice

新しい配列を返すので、戻り値で上書きすることで更新が検出される。

this.list = this.list.filter(function(el) {
  return el.hp >= 100;
});

外部データ取得のタイミング

ライフサイクルフックのcreatedがちょうどよい。

created: function() {
  axios.get('list.json').then(function(response) {
    this.list = response.data;
  }.bind(this)).catch(function(e) {
    console.error(e);
  });
}

DOMを直接参照する$elと$refs

DOMへのアクセスが必要なケース、たとえば要素の画面上の位置や高さはDOMでなければわからない。インスタンスプロパティ$elと$refsを使用するとDOMへアクセスできる。(mounted以降で使用可能)
$elはルート要素、$refsはref属性指定。

console.log(this.$el); // ルート要素
console.log(this.$refs.hello); // <p ref="hello">Hello World</p> 

テンプレート制御用ディレクティブ

  • v-onse
    一度だけ変数を評価し、リアクティブを解除
  • v-cloak
    インスタンスの準備が終わると消える属性
  • v-pre
    テキストをそのまま表示、Mustacheもそのまま文字列として表示
  • v-html
    HTMLタグ有効化
  • v-text
    要素内が単一のMastacheの場合はv-textでもよい
    (<span>{{ msg }}</span><span v-text="msg"></span>と同じ)

コメント