Vue.jsの入門書である基礎から学ぶVue.js(猫本)を前半の5章まで読みました。後半は今の自分には難しい&使わない部分も結構ありそうなので、前半部分の基本知識をざっくり整理します。
なお自分の知識としてはHTML,CSSが少しだけできる、生JavaScript、jQueryもまあ少しだけできるかなという程度です。jQueryしか知らないとマズイ時代なのかと感じ人気のある猫本を読み始めました。
Qiitaの投稿も初めて(若干コワイ)なのでお手柔らかにお願いします。間違っている部分や問題点があれば指摘お願いします。
1章
Vue.jsについて
Vue.jsはjavascriptのフレームワークです。
フレームワークとは、作成するアプリケーションの設計の骨組みのようなものです。この骨組みに沿って実装することで実装速度の上昇や設計をシンプルに保つことができる等のメリットが得られます。
Vue.jsはJavaScriptのフレームワークなので、普通のJavaScriptとは少し違う書き方を求められます。書き方を覚えてしまえばよりシンプルに実装することができます。
また、フレームワークと類似した言葉にライブラリがあります。
フレームワークが全体を構成するための骨組みだとすると、ライブラリは局所を埋める部品のようなものです。局所的な処理に対して既存のライブラリを用いたりコードをライブラリとして共通化することでやはり実装処理の上昇や処理の切り分けが期待できます。
なぜVue.jsなのか
Vue.js以外にもJavaScriptのフレームワークは色々あります。
代表的なものとしては、
- React.js
- Angular.js
等です。
これらのフレームワークについて全ての長所短所を調べたわけではないですが、少なくともVue.jsの良さとしては、
- 学習コストが低い
- スケールの柔軟性が高い
- 公式ドキュメント(日本語)の充実
が挙げられます。
Vue.jsでのHello world
- テキストバインディング
Vue.jsのhello world的なもの。
テンプレートにプロパティを記述するとその場所に値を入れて描画してくれます。
id="app"
とした部分にjsが適用されます。
<div id="app">
<p>{{ message }} </p>
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js'
}
})
<p>Hello Vue.js</p>
2章
データバインディング
上記コードのようにdata
オプションに文字列やオブジェクトなどのデータを定義することで、リアクティブデータを設定できます。
リアクティブデータというのは、Vue.js側でデータの取得時や更新時に自動的に反応してくれるデータのことです。
上記のコードではmessage
をリアクティブデータとすることで、DOM更新時にHello Vue.js
というテキストに変換してくれたということです。
また、このようなテキストバインディングの場合は{{ message }}
のように変換したい部分を中括弧で囲みます。この記法をMustache(マスタッシュ)と呼びます。
色々なデータバインディング
ネストと配列
new Vue({
el: '#app',
data: {
message: {
value: 'Hello Vue.js'
},
//配列にもできる
list: ['りんご', 'ばなな', 'いちご'],
//listから取り出す要素を動的にするためにセット
num: 1
}
})
<div id="app">
<p>{{ message.value }} </p>
<p>{{ message.value.length }} </p>
<p>{{ list[2]}} </p>
<p>{{ list[num] }} </p>
</div>
<p>Hello Vue.js</p>
<p>13</p>
<p>いちご</p>
<p>ばなな</p>
ifとshow
条件分岐によって対象の表示・非表示等を設定できます。
Vue.jsではv-if
とv-show
があります。
この際のv-if
やv-show
をディレクティブと呼びます。
v-〇〇
と書かれていれば、Vueで操作するために設定しているんだな、と思えばよいです。
<div id="app">
<div v-if="ok">v-if条件による描画</div>
<div v-show="ok">v-show条件による描画</div>
</div>
new Vue({
el: '#app',
data: {
ok: false
}
})
<!---->
<div style="display: none;">v-show条件による表示</div>
条件がfalseなので、v-if
はコメント化され、v-show
ではdisplay: none
が設定されていることがわかります。
for
v-for
ディレクティブを使います
<div id="app">
<ul>
<li v-for="item in list" v-bind:key="item.id">
ID. {{ item.id }} {{ item.name }} HP. {{ item.hp }}
</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
list:[
{ id: 1, name: 'スライム', hp: 100 },
{ id: 2, name: 'いっかくうさぎ', hp: 200 },
{ id: 3, name: 'ゴーレム', hp: 500 }
]
}
})
<div id="app">
<ul>
<li>ID.1 スライム HP.100</li>
<li>ID.2 いっかくうさぎ HP.200</li>
<li>ID.3 ゴーレム HP.500</li>
</ul>
</div>
v-for
のポイントはv-vind:key="item.id"
の部分です。繰り返し処理の場合はこのようにkey
属性をつけるようにします。
key
属性には不変かつユニークなものを設定するので、今回はitem.id
をセットしています。
3章
イベントハンドリング
「ボタンをクリックしたとき」というようにあるイベントに対しての処理を行うことをイベントハンドリングといいます。
JavascriptのaddEventListener
やjQueryの$(element).on
に相当します。
Vue.jsでは、v-on
ディレクティブを使用します。
<button v-on:click="handleClick">クリック</button>
new Vue({
el: '#app',
methods: {
handleClick: function() {
alert('クリックされました!')
}
}
})
ボタンをクリックすると、Vueインスタンスで設定したhandleClickが呼び出される、という流れです。
フォーム入力バインディング
フォームの入力値とデータと同期させることができます(双方向データバインディング)。
<div id="app">
<input v-model="message">
<p>{{ message }}</p>
</div>
new Vue ({
el: '#app',
data: {
message: 'Hello!'
}
})
簡単に入力値と画面上の値を同期させることができます。
4章
算出プロパティ
算出プロパティはその名の通り計算等の処理を含めることのできるデータのことです。
Mustache記法をする際に、テンプレート側に式を書いてしまうと見にくくなるので、算出プロパティとして設定することで可読性を保持できます。
計算したデータをcomputed
オプションに定義するかたちで実装します。
<p>{{ num }}の二倍は{{ doubleNum }}</p>
new Vue({
el: '#app',
data: {
num: 50
},
computed: {
doubleNum: function(){
return this.num * 2
}
}
})
フィルタ
フィルタとは文字列の操作処理に特化した機能です。
<div id="app">
{{ price | localeNum }}円
</div>
new Vue({
el: '#app',
data: {
price: 59800
},
filters: {
localeNum: function (val) {
return val.toLocaleString()
}
}
})
59,800円
5章
コンポーネント
コンポーネントとは、WebサイトのヘッダーやフッターなどのUIの部分ごとにテンプレートとJavaScriptをセットで持つことで、他のUIと切り離して管理できる機能です。
<div id="app">
<my-component></my-component>
</div>
Vue.component('my-component',{
template: '<p>MyComponent</p>'
})
new Vue({
el: '#app',
})
<div id="app">
<p>MyComponent</p>
</div>
コンポーネント間の通信
テンプレートで他のコンポーネントを使用すると親子関係になります。
親子間のデータのやりとりとして、
- 親からデータを
属性
として渡し、子はprops
で受け取る - 子からデータを
$emit
で渡し、親はon
で受け取る
という構造になります。
まずは親から子の場合
<comp-child val="子1"></comp-child>
<comp-child val="子2"></comp-child>
属性をval
として設定してます。
Vue.component('comp-child', {
template: '<p>{{ val }}</p>',
//受けとる属性名をpropsで指定
props: ['val']
})
new Vue({
el: '#app'
})
<p>子1</p>
<p>子2</p>
そして子から親の場合
<div id="app">
<comp-child v-on:childs-event="parentsMethod"></comp-child>
</div>
Vue.component('comp-child',{
template: '<button v-on:click="handleClick">押すとイベントが発火するボタン</button>',
methods: {
handleClick: function(){
this.$emit('childs-event')
}
}
})
new Vue({
el: '#app',
methods: {
parentsMethod: function(){
alert('イベントをキャッチしました!')
}
}
})
おわりに
マスコットキャラの猫のかわいいページランキング
1位. ライフサイクルで夜なのでおやすみ猫 p.45
2位. デプロイのたびに変更は面倒なリボン猫 p.237
3位. アニメーション・消える時の猫 p.201