JavaScript
jQuery
Vue.js

jQueryからVue.jsへ乗り換えてみた


はじめに

 この記事でQiitaデビュー?ですが、文書書くの下手くそなので、読みにくかったらすみません。

JavaScriptとjQueryで個人的に作りたかったマネーカウンター(コインカウンター)を題材に、仕事と趣味半々で作ってました。でも複雑怪奇になったのでVue.jsを使えば多分楽になると思って、移植しました。

 なお、PWAとして まねかん と、 Cordovaでラッピングして Androidアプリ「まねかん」 がありますので、参考まで。 ソースは GitHub においてあります。


「まねかん」制作のアイデア

 個人的にとある集会の会計をやっていて、小銭勘定を常に行う必要があったので、Excelで計算してたのですが、必ず手元にExcelがあるわけがないので、スマホアプリを作ろうと考えました。大元のExcelはこんな感じ。

image.png

 ただし、スマホアプリを一から設計するだけの余裕と技量が無いので、Webアプリの作り方をググっていくと、PWAとか便利な技術があることに気づきました。これならできると早速作成を開始しました。


jQueryの頃

 考え方は単純なので、感覚としては

<!DOCTYPE html>

<html lang="jp">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
</head>
<body>
<p>
<span>1円:</span>
<input class="count" type="number" value="0">
   <span class="subtotal s1">0円</span>
</p>
<p>
<span>5円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s5">0円</span>
</p>
<p>
<span>10円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s10">0円</span>
</p>
<p>
<span>50円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s50">0円</span>
</p>
<p>
<span>100円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s100">0円</span>
</p>
<p>
<span>500円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s500">0円</span>
</p>
<p>
<span>千円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s1000">0円</span>
</p>
<p>
<span>弐千円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s2000">0円</span>
</p>
<p>
<span>五千円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s5000">0円</span>
</p>
<p>
<span>壱万円:</span>
<input class="count" type="number" value="0">
<span class="subtotal s10000">0円</span>
</p>
<p>
<span class="total">0円</span>
</p>
<script>
let items = [
{type: 's1', callName: '1円', unit: 1},
{type: 's5', callName: '5円', unit: 5},
{type: 's10', callName: '10円', unit: 10},
{type: 's50', callName: '50円', unit: 50},
{type: 's100', callName: '100円', unit: 100},
{type: 's500', callName: '500円', unit: 500},
{type: 's1000', callName: '千円', unit: 1000},
{type: 's2000', callName: '弐千円', unit: 2000},
{type: 's5000', callName: '五千円', unit: 5000},
{type: 's10000', callName: '壱万円', unit: 10000}
];
$(function() {
$('input').on('change', function () {
let total = 0;
for (let i = 0; i < $('.count').length; i++) {
let c = Number($('input').eq(i).val());
let u = items[i].unit;
let subtotal = u * c;
total += subtotal;
$('.subtotal.' + items[i].type).text(`${Number(subtotal).toLocaleString()}円`);
}
$('.total').text(`合計:${Number(total).toLocaleString()}円`);
});
});
</script>
</body>
</html>

とデータを用意して、あとはinputタグだけで計算させてました。

あとはjQueryでイベント拾って計算させるだけという簡素な物でしたが、いろんなjQueryコンポーネントで装飾していくと、いろいろイベント処理とかが複雑になってきました。で、Vue.jsをつかうと楽になる的な情報を聞きました。


Vue.jsに移植

 Vue.jsは設計思想的には非常に合理的で、フォームの値が変わったら計算項目はすべて自動計算されるのが特徴です。jQueryだとDOMにイベントを割り当てて、関数を定義しなければいけませんが、基本の書き方をすれば、全部計算してくれます。

<!DOCTYPE html>

<html lang="jp">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p v-for="(item, index) in items">
<span>{{ item.callName }}</span><input type="number" v-model.number="item.counts"><span class="subtotal"> {{ subtotalMoney[index] }} 円</span>
</p>
<p>
<span>合計: {{ totalMoney }} </span>
</p>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
items: [
{callName: '1円', unit: 1, counts: 0},
{callName: '5円', unit: 5, counts: 0},
{callName: '10円', unit: 10, counts: 0},
{callName: '50円', unit: 50, counts: 0},
{callName: '100円', unit: 100, counts: 0},
{callName: '500円', unit: 500, counts: 0},
{callName: '千円', unit: 1000, counts: 0},
{callName: '弐千円', unit: 2000, counts: 0},
{callName: '五千円', unit: 5000, counts: 0},
{callName: '壱万円', unit: 10000, counts: 0}
]
},
computed: {
totalMoney: function () {
let total = 0;
for (let i = 0; i < this.items.length; i++) {
total += this.items[i].unit * this.items[i].counts;
}
return Number(total).toLocaleString();
},
subtotalMoney: function () {
let subtotals = [];
for (let i = 0; i < this.items.length; i++) {
subtotals.push(Number(this.items[i].unit *
this.items[i].counts).toLocaleString());
}
return subtotals;
}
}
});
</script>
</body>
</html>

 Vue.jsは見た目に難しいようですが意外と単純で、computed:節に計算する関数を書けば、いちいち関数をコールする必要もありません。

 jQueryだけだとイベントを一つ一つ書かなければいけませんが、すっきりします。


雑感

 何で先に Vue.js を覚えなかったのか?と思うほど動作を単純化できます。もちろん見栄えを良くするにはBootstrapとかで装飾したりでjQueryも必要ですけれども…

 そのうちVueコンポーネントの書き方でも書こうかなと思ってます。

 続き:Vue.jsのコンポーネントの作り方(たぶん初級編)


参考

Vue.js 公式サイト(日本語) https://jp.vuejs.org/index.html

jQuery 公式サイト(英語) http://jquery.com/