（５）Vuetifyでレスポンシブデザイン

VuetifyはPCとスマホの両方をサポートできるように、グリッドシステムを採用しています。今回は、Vuetifyでのグリッドの設定方法をみてみようと思います。

#参考ドキュメント

- [Vuetify GridSystem](https://vuetifyjs.com/en/components/grids/)

#グリッドを使ってレイアウトする

Vuetifyのグリッドは、Bootstrapなどと同様に、```<v-container>...</v-container>```の中に、```<v-row>...</v-row>```と```<v-col>...</v-col>```を使って、横が12のcolumnグリッドの中に、要素を置いていく方式を取っています。

![vcontainer1.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/86c03b1d-1e51-9f0a-7485-7892bca88914.png)


実際に、プログラムで確認してみましょう。まず、新しいプロジェクトを作ります。

```> vue create grid01```
```> cd grid01```
```> vue add vuetify```

全てDefaultを選択してください。

また、前回と同様、"src/components/HelloWorld.vue"を変更していきます。
グラフィックの表示を確認するためなので、上半分くらいだけ残してあとは、削除します。

```vue
<template>
  <v-container>
    <v-row class="text-center">
      <v-col cols="12">
        <v-img
          :src="require('../assets/logo.svg')"
          class="my-3"
          contain
          height="200"
        />
      </v-col>

      <v-col class="mb-4">
        <h1 class="display-2 font-weight-bold mb-3">
          Welcome to Vuetify
        </h1>

        <p class="subheading font-weight-regular">
          For help and collaboration with other Vuetify developers,
          <br>please join our online
          <a
            href="https://community.vuetifyjs.com"
            target="_blank"
          >Discord Community</a>
        </p>
      </v-col>
    </v-row>
  </v-container>
</template>
```

![vscode1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/43a5f426-eeb9-78cd-120d-a20c722e1cf0.png)

Terminalから、```>npm run serve```を実行してから、デバッガからブラウザを実行すると、以下のような画面がブラウザに表示されます。

![grid1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/53fee8ac-9fb0-ffe9-ccb5-4f4eeacfd0b0.png)

ここで、ロゴと"Welcome to Vuetify"のテキストを横に並べてみたいと思います。
4行目のlogo.svgを要素として持っているカラム```<v-col cols="12">```を、```<v-col cols="4">``` と変更すると、横に並んで表示されると思います。colsは、カラムの幅の指示をするための属性で、横幅は合計12になるように、なります。つまり、"Welcom to Vuetify"の文字列は、cols="8"となっています。

ここで、少しわかりやすくするために、それぞれのv-row, v-colの周りに線が表示されるようにします。
"HelloWorld.vue"の下に、以下を追加します。

```vue
<style>
.border {
  border: solid 1px;
}
</style>
```

さらに、2箇所の```<v-col>```のclassに```border```を追加してあげます。追加するところだけを以下に書いています。

```vue
<template>
  <v-container>
    <v-row class="text-center">
      <v-col cols="4" class="border">
        <v-img
          ...
        />
      </v-col>

      <v-col class="mb-4 border">
        <h1 class="display-2 font-weight-bold mb-3">
          Welcome to Vuetify
        </h1>
          ...
      </v-col>
    </v-row>
  </v-container>
</template>
```
![vscode2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/11a77d0c-1214-9ca0-fbbd-e48080c44018.png)

ブラウザでの表示は、以下のようになります。cols="4"とcols="8"で、1/3と2/3の割合で表示されていることがわかります。

![grid3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/dc912b0f-c7c2-628b-9fc7-dba31e1db10e.png)

#v-spacer

デザイン上、スペースを入れたいことがありますが、Vuetifyには、スペースをとるための```<v-spacer>```というタグがあります。ロゴと"Welcome..."の文字列の間に、さらにスペースを入れてみます。

```vue
<template>
  <v-container>
    <v-row class="text-center">
      <v-col cols="4" class="border">
        <v-img
          ...
        />
      </v-col>

      <v-spacer cols="1" />

      <v-col cols="7" class="mb-4 border">
        <h1 class="display-2 font-weight-bold mb-3">
          Welcome to Vuetify
        </h1>
          ...
      </v-col>
    </v-row>
  </v-container>
</template>
```

このとき、"Welcome..."の文字列にも、横幅の合計が12になるように、```cols="7"```を設定する必要があります。

![grid5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/96b40cab-8087-c9cf-4a66-e719da3d78b5.png)


#レスポンシブデザイン

横幅を狭くした時に、見やすくなるように、ロゴと文字列が縦に並ぶようにしてみましょう。

グリッドシステムでは、以下のようにユーザが使用している端末の横幅に合わせて、デザインを変更するようにできています。

![vcontainer.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/6c9f3303-9a67-65f8-15e6-047de6804ae2.png)



プログラムでは、横幅がどのくらい（何ピクセル）の時に、それぞれのレイアウトを切り替えるかを設定する必要があります。[Grid System](https://vuetifyjs.com/en/components/grids/)のドキュメントを見ると、Vuetifyでは、xs(<600px)から、xl（>1904px）まで５段階に分けてレイアウトを決められることがわかります。

例えば、xs(<600px)の時に、上記の一番右のレイアウト、つまり各要素が横幅100%となり、縦に一列に並ぶようにして、600pxを超えたら、横に並ぶようにするには、

1. xs(<600px）では、ロゴの横幅を100%とするために、ロゴに、```cols="12"```を指定する
2. sm（>600px）では、ロゴの横幅を33%とするために、ロゴに、```cols="4"```を指定する

とします。2.を指定するには、```sm=```を使って以下のように書きます。

```<v-col cols="12" sm="4">```

smが指定されれば、それより大きな画面では、smが使用されます。
実際に.vueファイルを修正して試してみましょう。

```vue
<template>
  <v-container>
    <v-row class="text-center">
      <v-col cols="12" class="border" sm="4">
...
      </v-col>

      <v-spacer cols="1"/>

      <v-col cols="7" class="mb-4 border">
...      </v-col>
    </v-row>
  </v-container>
</template>
```


![grid6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/0c3081f4-c247-5855-d5ef-8fb6e51d920a.png)

ブラウザの横幅を小さくしていくと、意図したように動作することが確認できると思います。また、ここでは、回り込んだためにスペースは削除され、"Welcome..."の文字列の幅は、```cols="7"``` で指定されているので、ロゴより狭くなっています。

#まとめ

Vuetifyのグリッドシステムを使って、レスポンシブデザインを実現する方法を見てみました。