くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Vue.jsでトップに戻るボタンをつけてみる

よく右下に出てくる一番上まで戻るボタンがほしいなと思い、やってみたときの備忘録。

主な流れ

  1. スクロールイベントに関数を登録
  2. 登録した関数で、スクロールされたら位置を保存しておく
  3. 位置が一定以上になったらボタンを表示する
  4. ボタンが押されたら上に移動する

こんな感じ。

1~3については、コンポーネントで完結するパターンもあるし、
カスタムディレクティブでやるパターンもあるっぽい

コンポーネント完結パターン

こんな感じ。

  1. mountedで、window.addEventListenerで登録
  2. handleScrollでスクロールされたらpositionに保存
  3. v-if="position > 500"で一定以上になったら表示
<template>
  <section class="container">
    <nuxt />
    <!-- Scroll Top Button -->
    <div class="btn-scrolltop" v-if="position > 500">
      <!-- 上に戻るボタン(中身は省略) -->
    </div>
    <!-- /Scroll Top Button -->
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";

@Component
export default class extends Vue {
  position: number = 0;
  
  mounted() {
    if (!process.browser) return;
    this.$nextTick(() => {
      window.addEventListener("scroll", this.handleScroll);
    });
  }
  
  handleScroll() {
    this.position = window.scrollY;
  }
}
</script>

カスタムディレクティブを使うパターン

あまり変わらないけど、最初だけ違う感じ、 ちょっと手間だけど、複数箇所で使うなら、良いかも。

  1. v-scroll="handleScroll"で、window.addEventListenerで登録
  2. handleScrollでスクロールされたらpositionに保存
  3. v-if="position > 500"で一定以上になったら表示
ディレクティブのプラグインを用意する

plugins/v-scroll.tsを用意して、
v-scrollでスクロールイベントを検知できるようにする。

import Vue from "vue";

Vue.directive("scroll", {
  inserted: function(el, binding) {
    let f = function(evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener("scroll", f);
      }
    };
    window.addEventListener("scroll", f);
  }
});
ディレクティブを使ってボタンのスクロール位置を取得
<template>
  <section class="container" v-scroll="handleScroll">
    <nuxt />

    <div class="btn-scrolltop" v-if="position > 500">
      <!-- 上に戻るボタン(中身は省略) -->
    </div>
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";

@Component
export default class extends Vue {
  position: number = 0;

  handleScroll() {
    this.position = window.scrollY;
  }
}
</script>

ボタンで一番上に戻る処理はvue-scrollto

上へ移動するとかはvue-scrolltoが便利なので、それを使う感じに♪
fade transionも合わせるとこんな感じでOK

<transition name="fade">
  <div class="btn-scrolltop" v-if="position > 500">
    <a class="button" v-scroll-to="'body'">
      <span class="icon">
        <i class="fas fa-lg fa-arrow-up"></i>
      </span>
    </a>
  </div>
</transition>

vue-scrolltoの詳しいことは別記事で。。(-_-;)

以上!!

おすすめの本

Vue.js入門 基礎から実践アプリケーション開発まで

Vue.js入門 基礎から実践アプリケーション開発まで

基礎から学ぶ Vue.js

基礎から学ぶ Vue.js

改訂新版 Vue.jsとFirebaseで作るミニWebサービス (技術の泉シリーズ(NextPublishing))

改訂新版 Vue.jsとFirebaseで作るミニWebサービス (技術の泉シリーズ(NextPublishing))

参考にしたサイト様