Vuetify.js 2.2のBottom navigationコンポーネントについて

# 概要

Bottom navigationコンポーネントの初歩的な使い方のまとめです。

**環境**

* Windows 10 Professional 1909
* Node.js 12.14.1
* Vue.js 2.6.11
* Vuetify.js 2.2.15

**参考**

* [Quick start - Vuetify.js] (https://vuetifyjs.com/en/getting-started/quick-start)
* [Components] (https://vuetifyjs.com/en/components/api-explorer)
* [Styles - Colors] (https://vuetifyjs.com/en/styles/colors)
* [Material Design Icons] (https://cdn.materialdesignicons.com/4.5.95/)

# [Bottom navigation] (https://vuetifyjs.com/en/components/bottom-navigation)

> The v-bottom-navigation is an alternative to the sidebar. It is primarily used on mobile and comes in two variants, icons and text, and shift.
> \-------------------------------------------------------------------------------------------
> v-bottom-navigationは、サイドバーの代替手段です。 主にモバイルで使用され、アイコンとテキスト、シフトの2つのバリエーションがあります。

上記に引用したとおり[ボトムナビゲーション] (https://vuetifyjs.com/en/components/bottom-navigation/)は、モバイルデバイスで使用することを想定した[ナビゲーションドロワー] (https://vuetifyjs.com/en/components/navigation-drawers/)の代替手段です。

## Props

### VBottomNavigation

* [VBottomNavigation] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.ts)
* [Applicationable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/applicationable/index.ts)
* [Positionable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/positionable/index.ts)
* [ButtonGroup] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/button-group/index.ts)
* [Colorable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/colorable/index.ts)
* [Measurable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/measurable/index.ts)
* [Proxyable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/proxyable/index.ts)
* [Scrollable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/scrollable/index.ts)
* [Themeable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/themeable/index.ts)
* [Toggleable] (https://github.com/vuetifyjs/vuetify/blob/v2.2.15/packages/vuetify/src/mixins/toggleable/index.ts)

```text
VBottomNavigation ---- Applicationable ---- Positionable
                  `--- Colorable
                  `--- Measurable
                  `--- Proxyable
                  `--- Scrollable
                  `--- Themeable
                  `--- Toggleable
```

|               |name           |type             |default   |relation                    |src       |
|:--------------|:--------------|:----------------|:---------|:---------------------------|:---------|
|**VBottomNavigation** |active-class|string       |<font color="blue"><strong>'v-btn--active'</strong></font>|v-btn                  |'v-btn--active'|
|               |background-color|string          |undefined |                            |          |
|               |grow           |boolean          |false     |v-btn                       |          |
|               |*height*       |number or string |<font color="blue"><strong>56</strong></font>|                            |56        |
|               |hide-on-scroll |boolean          |false     |                            |          |
|               |horizontal     |boolean          |false     |v-btn                       |          |
|               |*input-value*  |boolean          |<font color="blue"><strong>true</strong></font>|                            |true      |
|               |mandatory      |boolean          |false     |                            |          |
|               |shift          |boolean          |false     |v-btn                       |          |
|Applicationable|app            |boolean          |false     |v-app                       |          |
|Positionable   |absolute       |boolean          |false     |                            |          |
|               |fixed          |boolean          |false     |                            |          |
|Colorable      |color          |string           |undefined |                            |          |
|Measurable     |height         |number or string |-         |                            |          |
|               |max-height     |number or string |undefined |                            |          |
|               |max-width      |number or string |undefined |                            |          |
|               |min-height     |number or string |undefined |                            |          |
|               |min-width      |number or string |undefined |                            |          |
|               |width          |number or string |undefined |                            |          |
|Proxyable      |value          |any              |undefined |                            |          |
|Scrollable     |scroll-target  |string           |undefined |window                      |          |
|               |scroll-threshold|string or number|undefined |hide-on-scroll              |          |
|Themeable      |dark           |boolean          |false     |                            |null      |
|               |light          |boolean          |false     |                            |null      |
|Toggleable     |input-value    |boolean          |-         |                            |          |

* input-value : コンポーネントを表示するか非表示にするかを制御します。 .sync修飾子をサポートします。
* value : 現在アクティブなv-btnの値を保持します。 ボタンに値が指定されていない場合、代わりにそのインデックスが使用されます。

## 実装例

ボトムナビゲーションはVuetifyアプリケーションの一部（v-appコンポーネントに組み込み、v-bottom-navigationコンポーネントのappプロパティを指定する）として利用するほかに、Vuetifyアプリケーションとは別に単体で利用することもできます。
以下の実装例の動作結果は、Vuetifyアプリケーションの一部として実装したものになります。

```vue
<template>
  <v-app>
    <v-navigation-drawer app v-model="drawer">
      <!-- ドロワー -->
    </v-navigation-drawer>

    <v-app-bar app>
      <!-- アプリケーションバー -->
      <v-app-bar-nav-icon @click.stop="drawer = !drawer" />
    </v-app-bar>

    <v-content>
      <router-view />
    </v-content>

    <v-bottom-navigation app>
      <!-- ボトムナビゲーション -->
      <v-btn v-for="menu in menus" :key="menu.title" :to="menu.url">
        <span>{{ menu.title }}</span>
        <v-icon>{{ menu.icon }}</v-icon>
      </v-btn>
    </v-bottom-navigation>

  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    drawer: false,
    menus: [
      { title: 'Index', icon: 'mdi-web', url: '/' },
      { title: 'Home', icon: 'mdi-home', url: '/home' },
      { title: 'Favorites', icon: 'mdi-heart', url: '/favorites' },
      { title: 'About', icon: 'mdi-information-variant', url: '/about' }
    ]
  })
}
</script>
```

### テーマ

**dark**

`dark`プロパティでダークテーマを適用したボトムナビゲーションです
![bottom-nav-dark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/83e4e16e-d978-e879-605b-d572406a1f54.png)

**light**

`light`プロパティでライトテーマを適用したボトムナビゲーションです
![bottom-nav-light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/c2085ffa-6090-7f47-cafa-d645e73abd92.png)

### カラー

`color`はナビゲーションアイテム（ボタンやテキスト）の色、`background-color`はボトムナビゲーションの背景色を指定します。
図は`background-color`プロパティにlight-blueを指定したものです。
![bottom-nav-background-color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/6372632b-e7d6-2502-c801-34f47974e2fb.png)

#### アクティブカラー

選択中（アクティブな）のナビゲーションアイテムに適用するCSSクラス名を`active-class`プロパティで指定できます。デフォルトは`v-btn--active`という名前のCSSクラスです。
図は`active-class`プロパティにpinkを指定したものです。
![bottom-nav-active-class.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/5f67c2f1-cbeb-a80c-b2b8-4bafa9c84d3e.png)

### 表示の切り替え

`input-value`プロパティでボトムナビゲーションの表示切替を行います。このプロパティにバインドしたデータが`true`のときは表示され、`false`のときは非表示になります。（`hide-on-scroll`プロパティを指定すると、この`input-value`プロパティの値に関わらずスクロール時に表示／非表示が行われます。）
また、画面下部に固定されます。

### スクロール時に表示/非表示

`hide-on-scroll`プロパティを指定すると、非表示のときに下にスクロールすると表示され、表示されているときに上にスクロールすると非表示になります。
ボトムナビゲーションを`hide-on-scroll`プロパティだけで制御したい場合は`input-value`プロパティの値をfalseにしておくと良いかもしれません。

#### スクロールの閾値を設定

`scroll-threshold`プロパティでは、`hide-on-scroll`プロパティを指定したときにどれくらいスクロールしたら表示/非表示を行うかの閾値を指定します。
デフォルトではundefinedですが、動作確認すると400pxスクロールすると表示/非表示が行われました。

以下は100pxと500pxに指定したときの動作の違いです。

**scroll-thresholdが100px**
![bottom-nav-threshold-100.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/bdc88e60-47f6-b610-8a2b-9746ad383d17.gif)

**scroll-thresholdが500px**
![bottom-nav-threshold-500.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/13017394-0ffd-7e7b-fa03-d23e2e443d85.gif)

### 表示幅

`width`プロパティでナビゲーションの横幅を指定することができます。デフォルトはundefinedですが横幅いっぱいに表示されます。
`height`プロパティでナビゲーションの縦幅を指定することができます。デフォルトは56pxです。

**widthがundefined (デフォルト)**
図は画面の表示幅が900pxのときのものです。
![bottom-nav-width.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/0d364c7e-5dcc-406f-fe0b-646d149ba163.png)

**widthが600px**
図は画面の表示幅900pxのときにボトムナビゲーションの`width`プロパティを600pxに設定したものです。
![bottom-nav-width-600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/34d330cb-7222-e388-d924-296ee58903ec.png)

### ナビゲーションアイテムの表示スタイル

**デフォルト**
`grow`、`horizontal`、`shift`のいずれも指定しないときのナビゲーションアイテムの表示です。
![bottom-nav.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/f26174e1-7042-12e6-3efe-8135374008a6.png)

**grow**
`grow`プロパティを指定するとボタンの間隔が広くなります。
![bottom-nav-grow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/3605f8ba-1f92-89b1-71b5-cbc5cfdcf422.png)

**horizontal**
`horizontal`プロパティを指定するとボタンとテキストが横並びになります。
![bottom-nav-horizontal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/e6a8d674-79a6-f614-1021-1a5d276b5ac5.png)

**shift**
`shift`プロパティを指定するとアクティブなナビゲーションアイテムにだけテキストが表示されます。
![bottom-nav-shift.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/2186a417-d321-1ce8-5336-94eb774e2d60.png)