Vue.jsを利用したサイコロアプリ
コンポーネントとは
コンポーネント(Component) とはVue.jsでページを構成する部品のことです. ページの部分的な機能をコンポーネントとして実装することで,ページ内に複数配置したり再利用が可能になります. 今回は サイコロの目 をコンポーネントとして実装し,1から6の目を配置します.
サイコロアプリ
それでは サイコロアプリ を実装して行きましょう. 下記が完成したソースコードです. 「サイコロを振る」というボタンをクリックすると,1から6のいずれかの目が緑色になります.
See the Pen NWxpRYa by Naoto Mukai (@nmukai) on CodePen.
コンポーネントの作成
サイコロの目は div
タグで実装します.
まずは,div
タグをデザインするための CSS を下記のように記述します.
pipStyle
とpipFocus
の2つのクラスがあり,これをdiv
タグに適用します.
.pipStyle{
width: 50px;
height: 50px;
border: 1px solid black;
text-align: center;
display: table-cell;
vertical-align: middle;
}
.pipFocus{
background: #00ff00;
}
div{
margin: 5px;
}
pip
という名前でコンポーネントを実装します.
この名前はHTMLでタグ名として用いられます.
オプションには props
と template
を設定しています.
props
はpip
タグの属性として渡されるデータを指しています.
この場合,渡されたデータはflag
という変数に格納されます.
template
はコンポーネントをHTMLタグとして記述したときの実体であり,
ここではサイコロのマス目を表すdiv
要素です.
ここで,v-bind:class='{pipFocus: flag}'
に注目します.
これは,v-bind
ディレクティブを利用したCSSのクラスの設定を表しており,
flag
がtrueのときにだけ,pipFocus
を有効にすることを意味しています.
このようにv-bind
ディレクティブを用いてCSSの切り替えが可能です.
また,<slot></slot>
にも注目しましょう.
このslot
タグは特別な役割を持ち,pip
タグで囲まれた文字列を表します.
Vue.component("pip", {
props: ["flag"],
template: "<div class='pipStyle' v-bind:class='{pipFocus: flag}'> <slot></slot> </div>"
})
new Vue({
el: "#main"
});
コンポーネントを利用してHTMLを記述します.
pip
タグには,flag
属性を設定しています.
このflag
属性がtrue
のときだけ,pipFocus
が有効になるため,
サイコロの1の目だけが緑色になっていることが確認できます.
また,slot
タグはpip
タグで囲まれた文字列(1または2)に置き換わっています.
<div id="main">
<div>
<pip flag="true">1</pip>
<pip flag="false">2</pip>
</div>
<div>
<button>サイコロを振る</button>
</div>
</div>
Vueクラスの拡張
次にVueクラスを拡張し,サイコロの状態をデータバインディングで表現することにしましょう.
data
オプションで,サイコロの目を表すpips
配列と,クラスの有効を切り替えるflags
配列を定義しています.
new Vue({
el: "#main",
data: {
pips: ["1", "2", "3", "4", "5", "6"],
flags: [true, false, false, false, false, false]
}
});
上記のpips
配列とflags
属性を利用してHTMLを書き換えます.
このとき,v-for
ディレクティブを利用して,pips
要素の数だけpip
タグを生成しています.
ここで,(pip, i) in pips
はインデックス付きの繰り返しであり,pip
には配列の要素,i
には配列のインデックスが代入されます.
<div id="main">
<div>
<template v-for="(pip, i) in pips">
<pip v-bind:flag="flags[i]"> {{ pip }} </pip>
</template>
</div>
<div>
<button>サイコロを振る</button>
</div>
</div>
rollメソッドの実装
サイコロの目をランダムに決定するroll
メソッドを定義します.
配列のインデックスとなる0から5の乱数を生成し,
この値に応じてflags
配列のtrue
の位置を変更します.
このとき,Vue.set()
メソッドを利用して,
配列に変更があったことを知らせる必要があります(this.flags[i] = true;
では動的に変更されない).
new Vue({
el: "#main",
data: {
pips: ["1", "2", "3", "4", "5", "6"],
flags: [true, false, false, false, false, false]
},
methods: {
roll: function(){
dice = Math.floor(Math.random() * 6);
for(i=0; i<this.flags.length; i++){
if(i == dice){
Vue.set(this.flags, i, true);
}
else{
Vue.set(this.flags, i, false);
}
}
}
}
});
最後にv-on
ディレクティブでroll
メソッドを呼び出しましょう.
「サイコロを振る」をクリックすると,緑色の目がランダムに変更されれば完成です.
<div id="main">
<div>
<template v-for="(pip, i) in pips">
<pip v-bind:flag="flags[i]"> {{ pip }} </pip>
</template>
</div>
<div>
<button v-on:click="roll">サイコロを振る</button>
</div>
</div>