書籍「基礎から学ぶVue.js」のまとめ。
- 点数
- 感想
- まとめ
- 知識
- 基本
- バインディングされた変数へのアクセス
- ライフサイクルフック
- new Vue()は1回だけ実行するべき
- dataオプションに定義した変数は後から追加できない
- Mustacheは属性値には使用できない
- 全データの確認
- メソッドの短縮記法
- classとstyleのバインディング
- 複数属性のバインディング
- v-ifとv-show
- templateタグ
- v-else-if, v-else
- key属性による再利用可能な要素の制御
- v-for
- 変数の更新が検出されないケース
- Vue.setメソッド
- 元の配列を変更しないメソッドfilter, concat, slice
- 外部データ取得のタイミング
- DOMを直接参照する$elと$refs
- テンプレート制御用ディレクティブ
点数
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>
と同じ)