Vue.jsを使って簡単なカウンターアプリを作ってみた

最近Vue.jsの勉強を本格的に始めました。ひとまず何か簡単なものを作ろう！ということで、今回はカウンターアプリを作ってみました。良ければお試し下さい→[カウンターアプリ](https://takanoriokawa.github.io/CounterApp/)

##実現したいこと
1.ボタンをカチカチして数値を変更し、計算させる。
2.計算方法は足し算、引き算、掛け算、割り算を用意する。
3.計算方法の表記は、切り替えたタイミングで上に表示させる。


![app2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/5ad78c9c-d8bc-5b46-0774-412c607d280b.gif)


#コード
```html:index.html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>カウンターアプリ</title>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="app">
        <div id="container">
            <h1 class="title">{{title}}</h1>
            <div class="inputArea">
                <div class="top">
                    <button class="btn" @click="firstIncrement">+</button>
                    <button class="btn" @click="secondIncrement">+</button>
                </div>
                <h1 class="cal">{{first}} {{key}} {{second}} = {{resultAdd(key)}}</h1>
                <div class="bottom">
                    <button class="btn" @click="firstDecrement">-</button>
                    <button class="btn" @click="secondDecrement">-</button>      
                </div>
            </div>
            <div class="format">
                <button  class="changeBtn" @click="key = '+'">+</button>
                <button  class="changeBtn" @click="key = '-'">-</button>
                <button  class="changeBtn" @click="key = '×'">×</button>
                <button  class="changeBtn" @click="key = '÷'">÷</button>
                <button  class="changeBtn" @click="first = 0, second = 0">C</button>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script src="main.js"></script>
</body>
</html>
```



```scss:style.css
*{
    margin: 0;
    padding: 0;
    font-family: 'Oswald', sans-serif;
    touch-action: manipulation;
}
body{
    color: white;
    background-color: black;
}
#container{
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
button{
    color:black;
    background-color: white;
    outline: none !important;
    cursor: pointer;
}
.title{
    font-size: 45px;
    margin-bottom: 60px;
}
.cal{
    font-size: 50px;
    text-shadow: 3px 3px rgb(121, 121, 121);
}
.inputArea{
    width: 100%;
    height: 250px;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
    margin-bottom: 60px;
    & .btn{
        font-size: 30px;
        font-weight: 700;
        padding: 5px 10px;
        margin: 20px;
    }
    & .top,
    .bottom{
        margin-right: 70px;
    }
}
.changeBtn{
    font-size: 30px;
    font-weight: 700;
    padding: 5px 10px;
    margin: 0px 10px;
}
```



```javascript:main.js
new Vue({
    data:{
        first:0,
        second:0,
        sum:0,
        title:'addition',
        format:['Addition','Subtraction','Multiplication','Division'],
        key:'+',  
    },
    methods:{
        firstIncrement(){
            this.first += 1;
        },
        firstDecrement(){
            if(this.first > 0){
                this.first -= 1;
            }
        },
        secondIncrement(){
            this.second += 1;
        },
        secondDecrement(){
            if(this.second > 0){
                this.second -= 1;
            }
        },
    },
    computed:{
        resultAdd(){
            return function(f){
                if(f === '+'){
                    this.title = this.format[0];
                    return this.first + this.second;
                }else if(f === '-'){
                    this.title = this.format[1];
                    return this.first - this.second;
                }else if(f === '×'){
                    this.title = this.format[2];
                    return this.first * this.second;
                }else{
                    this.title = this.format[3];
                    this.sum = this.first / this.second;
                    return Math.round(this.sum * 1000) / 1000;
                }
            }
        },
    },
}).$mount("#app");
```
#methodsプロパティ
+ボタン、-ボタンをクリックすると、methodsプロパティのIncrementメソッド、Decrementメソッドが発火します。メソッド内ではdataプロパティに設定したfirstプロパティとsecondプロパティを参照し、値を加算、減算します。
メソッドからdataプロパティを参照する時はthisを忘れずに（よく忘れてエラーになります・・・）

#computedプロパティ
computedプロパティのresultAddではfirstやsecondの変更を検出して計算結果を返してくれます。
さらに今回は計算方法が4パターン欲しいので、resultAddに引数を持たせて、条件分岐をさせてみました。例えば渡された引数の文字列が「+」だったら、足し算の結果を返す。「×」だったら、掛け算の結果を返す。という感じです。

また、計算方法の変更は、下の「+」「-」「×」「÷」のボタンで変更しますが、これらのボタンが押された際も、resultAddが発火し、表記の変更をしつつ、変更した方法で計算結果を返してくれます。（computed便利！）

#割り算で四捨五入
割り算で割り切れない場合、結果が「3.33333333・・・」という感じで表示され、レイアウトが大変なことになるので、今回はMath.round関数を使って、小数点第四位を四捨五入しています。

#作ってみて
という感じで、簡単なカウンターアプリを作ってみました。
JavaScriptと比べるとVue.jsはコードが短く、簡潔に記述できるので、（もっと簡潔に書けるかもしれませんが、、）改めてフレームワークすご！！と思いましたね。


引き続きVue.js頑張りたいと思います！