Vue.js入門 Vol.3 ～基礎まとめで簡易家計簿を作る編～

こんにちは！
LIFULLエンジニアの吉永です。
本日も最近あまり関わらなくなったのであまりキャッチアップできていなかったフロントエンド開発技術についてインプットした内容を備忘録として記載していきます。

## 本記事の概要

[Vue.js入門 Vol.1 ～jQueryとの対比編～](https://qiita.com/YoshinagaYuta/items/278a0d6223952ecc7e29)
[Vue.js入門 Vol.2 ～jQueryとの対比編～](https://qiita.com/YoshinagaYuta/items/471fc5cb0cadc8910334)
上記2記事に続き、本記事はVue.jsの基礎まとめとして、簡易家計簿を作成するまでを解説します。
jQueryでフロントの知識が止まっていて最近キャッチアップできてないよって人のVue.jsへの入門に役立ててもらえると幸いです。
なお今回は簡単に扱えるCSSフレームワークである[BULMA](https://bulma.io/)を用いてHTMLをコーディングしております。
BULMA自体は非常に簡単なclass付けを行うだけで見た目が整ったGUIを簡単に構築できます。
今回の記事では詳細は解説しませんが、Bootstrapの経験があれば簡単に習得できると思います。

## 簡易家計簿の仕様

- [STEP1](#step1)
	- 入力項目は日付、項目、金額の3つとする。
	- 追加ボタンを押すとリストに追加される。
	- リストには複数の項目を追加できる。
- [STEP2](#step2)
	- 日付と項目が未入力の場合に追加ボタンを押された際にはリストに追加せず、エラーメッセージを表示する。
	- 追加ボタンを押した後に入力項目は初期化される。
- [STEP3](#step3)
	- リストに追加された行の一覧表示することができる。
	- リストに追加された行の合計値を表示することができる。
- [STEP4](#step4)
	- リストに1行もデータがない時はリストのカラム名や合計値は非表示にする。
- [STEP5](#step5)
	- リストでは任意の項目を削除することができる。

## 簡易家計簿の画面仕様

### 初期画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690018/75420347-4ed2-f6be-e0c5-c06986e39286.png)

### リスト表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690018/d47a9226-6120-e7a9-a5a0-ef171f193990.png)

## 簡易家計簿の完成品デモ

<p class="codepen" data-height="500" data-theme-id="dark" data-default-tab="result" data-user="yuta-yoshinaga" data-slug-hash="bGqogdx" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="簡易家計簿アプリ～完成版デモ～">
  <span>See the Pen <a href="https://codepen.io/yuta-yoshinaga/pen/bGqogdx">
  簡易家計簿アプリ～完成版デモ～</a> by Yuta Yoshinaga (<a href="https://codepen.io/yuta-yoshinaga">@yuta-yoshinaga</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 実装

それでは仕様に沿って簡易家計簿を実装していきます。

### STEP1

ここではSTEP1として、画面上に入力フォームを実装します。
実現する要件は下記の3点です。

- 入力項目は日付、項目、金額の3つとする。
- 追加ボタンを押すとリストに追加される。
- リストには複数の項目を追加できる。

#### STEP1 実装までの手順

1. まずは入力フォームのタグをinputで用意し、v-modelで双方向データバインディングできるように各項目に対応したモデル名を決める。
1. JS側でもVueオブジェクトの初期化コードと、dataに双方向データバインディングするモデルの定義を追加する。
1. 追加ボタンをbuttonタグで追加し、v-on:clickでクリックされた際に呼び出される関数addNewItemを記述する。
1. JS側でv-on:clickに記述した関数addNewItemをmethodsに追加する。
1. addNewItem関数内で入力フォームに入力された情報を取得できる関数getNewItemを追加する。
1. getNewItemで取得したオブジェクトをitems配列に追加する。
1. リストに追加されているのかを確認する為、画面の一番下に`<pre>{{ $data }}</pre>`を追加して、デバッグ用の情報を画面に出力できるようにする。

#### STEP1 実装例

上記手順の通りに実装した例が下記になります。

<p class="codepen" data-height="700" data-theme-id="dark" data-default-tab="js,result" data-user="yuta-yoshinaga" data-slug-hash="PopJbYz" style="height: 700px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="簡易家計簿アプリ～STEP1～">
  <span>See the Pen <a href="https://codepen.io/yuta-yoshinaga/pen/PopJbYz">
  簡易家計簿アプリ～STEP1～</a> by Yuta Yoshinaga (<a href="https://codepen.io/yuta-yoshinaga">@yuta-yoshinaga</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>



### STEP2

ここではSTEP2として、入力チェックと入力後の画面初期化を実装します。
実現する要件は下記の2点です。

- 日付と項目が未入力の場合に追加ボタンを押された際にはリストに追加せず、エラーメッセージを表示する。
- 追加ボタンを押した後に入力項目は初期化される。

#### STEP2 実装までの手順

1. 未入力をチェックする為の関数checkNewItemをmethodsに追加する。
1. 未入力時のエラーメッセージを表示する為の関数getErrorMessageをmethodsに追加する。
1. リスト追加完了後に入力フォームを初期化する為の関数clearNewItemをmethodsに追加する。
1. addNewItem関数内の処理を、リスト追加前にcheckNewItemで未入力チェックを行い、未入力ならgetErrorMessageで取得したエラーメッセージを表示して、リターンするように変更。
1. addNewItem関数内の処理を、リスト追加後にclearNewItemで入力フォームを初期化するように変更。

#### STEP2 実装例

上記手順の通りに実装した例が下記になります。

<p class="codepen" data-height="1300" data-theme-id="dark" data-default-tab="js,result" data-user="yuta-yoshinaga" data-slug-hash="mdWBOXR" style="height: 1300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="簡易家計簿アプリ～STEP2～">
  <span>See the Pen <a href="https://codepen.io/yuta-yoshinaga/pen/mdWBOXR">
  簡易家計簿アプリ～STEP2～</a> by Yuta Yoshinaga (<a href="https://codepen.io/yuta-yoshinaga">@yuta-yoshinaga</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### STEP3

ここではSTEP3として、前ステップで実装した追加されたリストデータを画面へ表示する部分を実装します。
実現する要件は下記の2点です。

- リストに追加された行の一覧表示することができる。
- リストに追加された行の合計値を表示することができる。

#### STEP3 実装までの手順

1. HTML側でv-forを使ってitemsの内容を表形式で表示できるようにする。
1. JS側でitemsのpriceの合計値を計算して返却できる関数getItemTotalPriceをmethodsに追加する。
1. HTML側でitems内のpriceの合計値を表示できるようにマスタッシュ構文を使ってgetItemTotalPrice関数を呼び出せるようにする。

#### STEP3 実装例

上記手順の通りに実装した例が下記になります。

<p class="codepen" data-height="1000" data-theme-id="dark" data-default-tab="html,result" data-user="yuta-yoshinaga" data-slug-hash="VwpMmqm" style="height: 1000px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="簡易家計簿アプリ～STEP3～">
  <span>See the Pen <a href="https://codepen.io/yuta-yoshinaga/pen/VwpMmqm">
  簡易家計簿アプリ～STEP3～</a> by Yuta Yoshinaga (<a href="https://codepen.io/yuta-yoshinaga">@yuta-yoshinaga</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### STEP4

ここではSTEP4として、リストに1行もデータがない時に表を非表示にする部分を実装します。
実現する要件は下記の1点です。

- リストに1行もデータがない時はリストのカラム名や合計値は非表示にする。

#### STEP4 実装までの手順

1. HTML側でリスト表示部分の親エレメントにv-ifでitemsのlengthが0でないなら表示するようにする。

#### STEP4 実装例

上記手順の通りに実装した例が下記になります。

<p class="codepen" data-height="1000" data-theme-id="dark" data-default-tab="html,result" data-user="yuta-yoshinaga" data-slug-hash="wvJrobj" style="height: 1000px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="簡易家計簿アプリ～STEP4～">
  <span>See the Pen <a href="https://codepen.io/yuta-yoshinaga/pen/wvJrobj">
  簡易家計簿アプリ～STEP4～</a> by Yuta Yoshinaga (<a href="https://codepen.io/yuta-yoshinaga">@yuta-yoshinaga</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### STEP5

ここではSTEP5として、リスト内から任意のデータを削除する部分を実装します。
実現する要件は下記の1点です。

- リストでは任意の項目を削除することができる。

#### STEP5 実装までの手順

1. JS側でリスト内の何番目の要素を削除するかを引数に持つdeleteItemをmethodsに追加する。
1. HTML側のv-forにループ処理の何番目からの情報を受け取る為にindexを追加する。
1. HTML側で一覧表示の行の末尾に削除ボタンを追加して、v-on:clickでdeleteItemを呼び出せるようにする。その際リスト内の何番目かを示すindexを引数に渡す。

#### STEP5 実装例

上記手順の通りに実装した例が下記になります。

<p class="codepen" data-height="1000" data-theme-id="dark" data-default-tab="html,result" data-user="yuta-yoshinaga" data-slug-hash="QWpqGeJ" style="height: 1000px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="簡易家計簿アプリ～STEP5～">
  <span>See the Pen <a href="https://codepen.io/yuta-yoshinaga/pen/QWpqGeJ">
  簡易家計簿アプリ～STEP5～</a> by Yuta Yoshinaga (<a href="https://codepen.io/yuta-yoshinaga">@yuta-yoshinaga</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 最後に

いかがでしたでしょうか？
Vue.jsを使って入力フォームからの入力をリストに追加、リストの表示、合計値の表示、リスト内から任意の項目を削除などを実装しました。
同じものをjQueryで実装する場合はデータの持ち方をどうするか？そのデータをどうやって表示に反映させるか？などを考慮しながらエレメントの操作を行う必要がありますが、Vue.jsだと画面で行われた操作に対して裏側で行ったデータ操作をプログラマが意識することなく画面に反映してくれるので、ロジックに集中することができるなぁというのが今回の簡易家計簿を作ってみての感想です。

それではまた次の記事でお会いしましょう！