Vuetifyを使ってデザインをつけてみた

今回の記事は前回の記事の続編で、Vuetifyを使って、デザインを整えていきたいと思います。

前回の記事ではGraphQLでDynamoDBに保存されたデータを実際に画面上に出力する方法を記載しているので、興味のある方は是非見てみてください
[GraphQL+DynamoDBを使って画面にデータを出力して見た](https://qiita.com/respectakagikun/items/361d674c52770fe9c2ceを参照してみてください。)

## 環境

* Pug を使用
* VuetifyのコンポーネントをUIで使用
* コーディング規約は Nuxt.js に則って StandardJS
* Visual Studio Code 

## 現状

部屋番号はsortされているが、デザインがない状態

<img width="1202" alt="スクリーンショット 2019-11-26 22.36.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/f7ece264-89cb-2ac6-fb16-156d81877603.png">

## データ構造
現在以下のようなデータ構造です
<img width="1029" alt="スクリーンショット 2020-01-14 22.43.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/8fffc0dc-c6fd-1fab-d74a-c6fa5541ba10.png">


## v-iconを使ってみよう
`v-icon`コンポーネントを使って好きなアイコンを使ってみます。アイコンの一覧は公式の[Material Icons](https://material.io/resources/icons/?style=baseline)にページにまとめられてあります。

部屋のタイプに合わせてアイコンを以下のように表示させていこうと思います。
※アイコンの種類には特に拘っていないのでご了承ください。

| Type |  Icon  |
| ---- | ---- |
|  single  |  person  |
|  double  |  wc  |
|  triple  |  people  |
|  family  |  home  |

## 実際にv-iconを表示させてみる
switch文を使い、部屋のデータに合わせて、v-icon名を返す`getRoomTypeIcon`メソッドを用意しました

```javascript:methods

getRoomTypeIcon (room) {
      if (room.guestInfo) {
        switch (room.type) {
          case 'single':
            return 'person'
          case 'double':
            return 'wc'
          case 'triple':
            return 'people'
          case 'family':
            return 'home'
        }
      }
      return 'no_meeting_room'
    }
```

Vue上で`getRoomTypeIcon`メソッドを呼び出してあげましょう

```javascript:home.vue
<template lang="pug">
v-container
   v-layout(
        row
        wrap
      )
        v-flex(
          xs12
          sm6
          md4
          lg4
          v-for="room in rooms"
          :key="room.name"
        )
          v-card.ma-3(
            flat
          )
            v-card-title
              | {{ room.number }}
              v-spacer
              span.mr-1(
               ) {{ room.status }}
            v-card-text(
               style="text-align:center; font-size:24px;"
            )
              v-icon(
                large
              ) {{ getRoomTypeIcon(room) }}
              v-spacer
               span(
                v-if="room.guestInfo"
               ) {{ room.guestInfo.name }}
</template>
```

以下のようにデザインが変わります。いい感じですね。

<img width="1149" alt="スクリーンショット 2020-01-14 22.42.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/d887ca95-ec4a-954e-7c73-cbe17956bacc.png">

## ２つの日付の差を求めてみる

宿泊者のデータには宿泊開始日(`startedAt`)とチェックアウトをする日(`leavesAt`)のデータを持っています。
何日間宿泊するか、各部屋ごとに表示させていきたいと思います。

あらかじめjavascriptが用意してくれている組み込み関数new Dateオブジェクトを使って日数の差を計算していきます。

```javascript:methods

getRoomDate (room) {
      if (room.guestInfo) {
        const day1 = new Date(room.guestInfo.startedAt)
        const day2 = new Date(room.guestInfo.leavesAt)
        const termDay = (day2 - day1) / 8640000 //24 * 60 * 60 * 1000

        return termDay
      } else {
        return 0
      }
    }

```

`termDay`で`day2`から`day1`の差を求めた後、 86400000で割っているのは、
DateオブジェクトからDateオブジェクトを引くとミリ単位で値が返ってくるからです。
そのため、値を１日分のミリ秒（24時間ｘ60分ｘ60秒ｘ1,000ミリ秒＝86,400,000ミリ秒)である事で日数を求めます。
※参考：[DateオブジェクトMDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date)

Vue上で`getRoomDate`メソッドを呼び出してあげましょう

```javascript:home.vue
<template lang="pug">
v-container
  v-layout(
        row
        wrap
      )
        v-flex(
          xs12
          sm6
          md4
          lg4
          v-for="room in rooms"
          :key="room.name"
        )
          v-card.ma-3(
            flat
          )
            v-card-title
              | {{ room.number }}
              v-spacer
              span.mr-1(
               ) {{ room.status }}
            v-card-text(
               style="text-align:center; font-size:24px;"
            )
              v-icon(
                large
              ) {{ getRoomTypeIcon(room) }}
              v-spacer
               span(
                v-if="room.guestInfo"
               ) {{ room.guestInfo.name }}
             v-card-actions
                div.mr-2
                  v-icon.mr-1(
                    small
                  ) event
                  | {{ getRoomDate(room) }} {{ "days" }}

</template>

```

以下のようにデザインが変わりました。
<img width="1139" alt="スクリーンショット 2020-01-15 0.14.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/937bc71f-35a4-09e4-f9ee-ab1354a37c87.png">

vuetifyのアイコンを中心に紹介していきました。最近[ライブラリが新調され](https://materialdesignicons.com/)他にもデザインを豊かにするコンポーネントがたくさん用意されています。是非試してみてください！