192
204

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-04-15

はじめに

 この記事で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/

192
204
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
192
204

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?