Vue 3でスクロールすると出てくる「トップへ戻る」ボタンの作り方

Vue.js

Vue.jsのv3(composition APO)でスクロールすると出てくる「トップへ戻る」ボタンの作り方を紹介します。

Vue 3で「トップへ戻る」ボタンの作り方

index.html

アイコンを使いたいので、今回はBoxiconsを使用します。

<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>

publicフォルダのindex.htmlのheadタグ内にlinkを差し込みます。

この方法か、npmを使う方法があります。

template

<template>
  <a
    href="#"
    class="scrolltop"
    @click="scrollTop"
    :class="{'show-scroll' : scrollHeader}">
    <i class='bx bxs-chevron-up scrolltop__icon' ></i>
  </a>
</template>

templateタグでは、Boxiconsより取得したiタグのアイコンフォントをaタグで囲ってリンクにします。
aタグでは、scrollHeaderがtrueのときshow-scrollクラスが付与されるように動的なclassを作成します。
この動的なクラスで一定のところまでスクロールしたときに、上へ戻るボタンとなるスクロールトップのボタンを表示させます。

クリックしたときに上へ戻るようにするためにscrollTopというメソッドを指定しておきます。
また、iタグではアイコンの装飾をしています。

script

<script>

import { onMounted, ref } from 'vue';

export default {
  setup() {
    const scrollHeader = ref(false)

    function showScrollTop() {
      if(window.scrollY >= 560) {
        scrollHeader.value = true
      } else {
        scrollHeader.value = false
      }
    }

    function scrollTop() {
      if(window.scrollY >= 560) {

          window.scrollTo({
            top: 0,
          behavior:'smooth'
        })
      }
    }
    onMounted(() => {
    window.addEventListener("scroll", showScrollTop, { passive: true })
    })

    return {
      scrollTop,
      scrollHeader,
      showScrollTop,
    }
  }

}</script>

まず、onMountedとrefを使うので、vueからimportします。
setup内では、true/falseのscrollHeaderを定義します。
ある一定のところまでスクロールされたら、表示したいという場合、window.scrollYでその値を取得できます。
window.scrollYは、現在のビューポートの一番上からのY座標をピクセル数で値が返されます。
それを、コンソールなどでよい位置を確認して設定します。
上の例では560としています。
560以上なら、scrollHeaderをtrueに(上へ戻るボタンを表示)、そうでないならfalse(上へ戻るボタンを非表示)にする関数を作成します。

そして、スクロールするには、window.scrollToを使います。
topからの位置を指定します。一番上に戻りたい場合は0を指定します。
behaviorでは、smoothを指定するとスルスルとなめらかに動きます。

そして、mountされたときに、スクロールを検知できるようにonMountedでイベントリスナーを設定します。
{ passive: true }にすることで、eventのpreventDefault()を関数内で使用しませんよとブラウザに伝えることができます。
そうすることで、ブラウザが画面描写とリスナー内の関数の実行を非同期的に処理できるようになります。
カクつき防止にも有効です。

style

<style lang="scss" scoped>
  .scrolltop {
    position: fixed;
    right: 1rem;
    bottom: -20%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: .5rem;
    background-color: rgba(123,111,113,.7);
    border-radius: .5rem;
    z-index: var(--z-tooltop);
    transition: .4s;
    visibility: hidden;

    &:hover {
      background-color: var(--first-color);
    }

    &__icon {
      font-size: 2rem;
      color: var(--first-color-lighten);
    }
  }

  .show-scroll {
    visibility: visible;
    bottom: 1.5rem;
  }</style>

show-scrollで上へ戻るボタンの表示・非表示を制御しているので、visibilityを操作します。
また、下から出てくるような簡単なトランジションを加える場合は、bottomの値を上へ戻るボタンの表示・非表示のcssで違う値を設定します。

Vue.js

Posted by devsakaso