Floating Action Button でスクロール制御

# Floating Action Button でスクロール制御
この記事は[サーバーレスWebアプリ Mosaic](https://mosaic.w2or3w.com "Mosaic")を開発して得た知見を振り返り定着させるための[ハンズオン記事](https://qiita.com/w2or3w/items/87b57dfdbcf218de91e2)の1つです。

以下を見てからこの記事をみるといい感じです。
* [Vue CLIで新規プロジェクト作成と、よくある雛形の実装](https://qiita.com/w2or3w/items/20d393560571f1531041)

## イントロダクション
最近のアプリで良く見かける、ずっと定位置にあるあのボタン。
最近のアプリで良く見かける、するする〜っとなめらか〜にスクロールするあの機能。
それらをVueのWebアプリに実装します。

## コンテンツ
この記事では以下のキャプチャのように、右下にフローティングアクションボタンを設置します。
このボタンをフワッと表示させたり、押下によりスルスルゥ〜っと上方向へスクロールさせたりします。
![Screenshot 2020-01-05 at 22.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394775/e51fa74a-ac2a-0493-46e2-15c558998901.png)


### フローティングアクションボタンの設置

```src/App.vue
      :
    <v-btn fixed fab bottom right color="#BDBDBD88" style="bottom: 100px">
      <v-icon color="white">mdi-chevron-up</v-icon>
    </v-btn>
      :
```
色はグレーで、洒落っ気を出して半透明にしました。

### フローティングアクションボタンをフワッと表示したり非表示したりする

```src/App.vue
      :
    <transition name="fade">
      <v-btn fixed fab bottom right color="#BDBDBD88" style="bottom: 100px" v-show="this.isShowUp">
        <v-icon color="white">mdi-chevron-up</v-icon>
      </v-btn>
    </transition>
      :
<script>
      :
  mounted() {
    window.addEventListener("scroll", this.onScreenEvent);
    window.addEventListener("resize", this.onScreenEvent);
    window.addEventListener("load", this.onScreenEvent);
  }, 
  methods:{
    onScreenEvent() {
      this.isShowUp = window.pageYOffset >= 32;
    } 
  }
};
</script>
<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}

</style>
```
フワッと表示/非表示させるために`<transition name="fade">`でボタンを囲い、表示条件は`v-show`で指定します。

### フローティングアクションボタンを押下したらスルスルゥ〜っとスクロールさせる
`vue-scrollto`というライブラリを利用するためにインストールします。

```
$ npm install vue-scrollto
```

```src/App.vue
<template>
  <v-app>
    <div id="return-to-top"></div>
      :
    <transition name="fade">
      <v-btn fixed fab bottom right color="#BDBDBD88" style="bottom: 100px" v-show="this.isShowUp"
        v-scroll-to="{ element: '#return-to-top', duration: 1000 }"
      >
        <v-icon color="white">mdi-chevron-up</v-icon>
      </v-btn>
    </transition>
      :
```
durationの数を大きくすると、よりゆっくりスクロールさせられます。
同じような感じで下側へスクロールさせることもできますので、今回ははしょりますが、必要な場合は調べて実装してみてください。

App.vue全体のコードも載せておきますね。

```src/App.vue
<template>
  <v-app>
    <div id="return-to-top"></div>
    <v-navigation-drawer app v-model="drawer">
      <v-list nav dense>
        <v-list-item-group>
          <v-list-item>
            <v-list-item-title>HOME</v-list-item-title>
          </v-list-item>
          <v-list-item>
            <v-list-item-title>ABOUT</v-list-item-title>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-navigation-drawer>

    <v-app-bar app>
      <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
      <v-toolbar-title>
        Sample Vue Project
      </v-toolbar-title> 
    </v-app-bar>

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

    <v-footer app>
      <v-card-title>
        <v-btn fab small class="mx-2" color="white" href="https://twitter.com/w2or3w" target="_blank">
          <v-icon>mdi-twitter</v-icon>
        </v-btn>
        <v-btn fab small class="mx-2" color="white" href="https://www.facebook.com/w2or3w" target="_blank">
          <v-icon>mdi-facebook</v-icon>
        </v-btn>
        <v-btn fab small class="mx-2" color="white" href="https://www.instagram.com/w2or3w" target="_blank">
          <v-icon>mdi-instagram</v-icon>
        </v-btn>
      </v-card-title>
      <v-card-text>
        <p>Copyright © Sample Vue Project</p>
      </v-card-text>
    </v-footer>

    <transition name="fade">
      <v-btn fixed fab bottom right color="#BDBDBD88" style="bottom: 100px" v-show="this.isShowUp"
        v-scroll-to="{ element: '#return-to-top', duration: 1000 }"
      >
        <v-icon color="white">mdi-chevron-up</v-icon>
      </v-btn>
    </transition>

  </v-app>
</template>

<script>
import Vue from "vue";
import VueScrollTo from "vue-scrollto";
Vue.use(VueScrollTo, {
  container: "body",
  easing: "ease", 
  cancelable: true
});

export default {
  name: 'App',
  data: () => ({
    drawer: false,
    isShowUp: false,
  }),
  mounted() {
    window.addEventListener("scroll", this.onScreenEvent);
    window.addEventListener("resize", this.onScreenEvent);
    window.addEventListener("load", this.onScreenEvent);
  }, 
  methods:{
    onScreenEvent() {
      this.isShowUp = window.pageYOffset >= 32;
    } 
  }
};
</script>
<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>
```

## あとがき
フローティングアクションボタンっていうんですね、あの浮いてるボタン。
フワッと表示/非表示させたり、スルスルゥ〜っと動かしたり、最近のUIはしゃらくさいですよね。
この「フワッ表示」とか「スルスルゥ〜っとスクロール」にも実は正式名称があったりするのでしょうか。ソフトアピアとか、スムーススクロールとか？
いやー、しゃらくさいですね。