Vue.jsを勉強してみた
仕事で今月から開発のフェーズに入り、フロントエンドをVue.jsのフレームワークで開発することになりました。脱JQuery、そしてMVVMの考え方に慣れるために、勉強したことのアウトプットをQiitaにまとめておきます。
今回のアウトプット
来週友人の結婚式がありビンゴ係に任命されているため昔作ったビンゴマシーンをVue.jsで新たに作り直しました。ソースについてはGithub上で公開しているので、ぜひ動かしてみてください!(マサカリも歓迎です)
Vue.jsの概要
Vue.jsの特徴
Vue.jsは、双方向データバインディングができるというのが大きな特徴で、データを更新したら画面(UI)が更新される。画面(UI)が更新されたらデータが更新されるというような、シングルページアプリケーションにとても相性がいいと思います。
画面から非同期でサーバにリクエストを送り、取得したデータで必要な箇所のみをバインディングして描画することで、速いアプリケーションを構築することが可能になります。
作ったもの
成果物
https://the-bingo.jp
※ドラムロールとシンバルの音が流れます
成果物のイメージ
使った技術
- Vue.js
- JQuery
- SemanticUI - CSSフレームワーク
制作時間
6時間ほど
ビンゴマシンの仕様
- ① 1〜75までの番号をランダムで表示する(重複はなし)
- ② 選択された番号は下の表示欄を黄色にする
- ③ ENTERキー押下だけで操作可能(スタート&ストップ)
ソースコード
<!DOCTYPE html>
<html lang="en">
<head>
<title>ビンゴマシン</title>
<link rel="stylesheet" type="text/css" href="assets/semantic/semantic.css">
<link href="assets/css/style.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<container id="app">
<div>
<div class="panel" id="panel1">︎{{panel1}}</div>
<div class="panel" id="panel10">{{panel10}}</div>
</div>
<div class="ui centered grid">
<div class="two wide tablet computer center aligned padded column">
<button id="stopButton" v-model="stopButton" v-disable="stopButton" v-on:click="runStop()" class="ui fluid big blue button">STOP</button>
</div>
</div>
<div class="ui centered grid">
<div class="five wide tablet computer center aligned padded column">
<button id="spinButton" v-model="spinButton" v-disable="spinButton" class="ui fluid red button" v-on:click="runSlot()">SPIN</button>
</div>
</div>
<div class="ui centered grid">
<div class="nine wide tablet computer center aligned padded column">
<div class="container">
<div class="bingo" v-bind:style="pStyle" v-bind:id="item" v-for="item in items">
{{ item }}
</div>
</div>
</div>
</div>
</div>
<div></br></br>
<div class="copy">By <a href="https://twitter.com/Fujiyama_Yuta">@Fujiwara_Yuta</a>, Thanks to @Ishi </div>
</div>
</container>
</body>
<audio id="audio_drum" src="assets/audio/drumroll.wav"></audio>
<audio id="audio_cymbal" src="assets/audio/cymbal.wav"></audio>
<script type="text/javascript" src="assets/js/bingo.js"></script>
</html>
(function() {
'use strict';
var slotTimer;
var drumRoll = document.getElementById('audio_drum');
var cymbal = document.getElementById('audio_cymbal');
var bingoNumArray = Array.from(new Array(75)).map((v, i) => i+1)
var bingoNumer = "0";
var setNum = "0";
var vm = new Vue({
el: '#app',
data: {
items: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12','13','14','15',
'16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30',
'31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45',
'46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60',
'61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75',],
panel1:"0",
panel10:"0",
spinButton:false,
stopButton: true,
pStyle:"",
bingoId:"0"
},
methods: {
runSlot: function () {
drumRoll.play();
cymbal.pause();
this.spinButton = true;
this.stopButton = false;
var bingoNum = bingoNumArray.length;
if (bingoNum==0){
return;
}
bingoNumer = Math.floor(Math.random() * bingoNum).toString();
setNum = bingoNumArray[bingoNumer];
if (parseInt(setNum) < 10){
setNum = '0' + setNum;
}
setNum = setNum.toString();
this.panel1 = setNum.substr(0, 1);
this.panel10 = setNum.substr(1, 2);
slotTimer = setTimeout(this.runSlot, 25);
},
runStop: function () {
clearInterval(slotTimer);
cymbal.play();
drumRoll.pause();
this.spinButton = false;
this.stopButton = true;
cymbal.currentTime = 0;
drumRoll.currentTime = 0;
bingoNumArray.splice(parseInt(bingoNumer),1);
var id = setNum;
$('#' + id).addClass("unmatched");
}
},
directives: {
disable: function (el, binding) {
el.disabled = binding.value
}
}
});
$("body").keypress(function (event) {
if (event.which === 13) {
console.log("ENTER");
$('#spinButton').click();
$('#stopButton').click();
}
});
})();
まとめ
開発ではずっとJQueryを使っていたため、Vue.jsのMVVMに慣れない部分は多々ありますが、双方向のデータバインディングはとても便利なので、今後も積極的に使っていきたいですね!