こんにちは、”はふぃ”です。

アンカーリンクとは、リンクしたい場所にアンカー(目印)を置いてページ内ジャンプをするための機能のことで、htmlでは飛び先の要素にid=”アンカー名”、リンクにhref=”#アンカー名”を設定することで実装できます。

簡単に実装できて便利なアンカーリンクですが、以前
【Vue.js】watchを使ったTipsの記事でも少し触れたように、Vue.jsではidを指定するだけではアンカーリンクがうまく機能しないことがあります

例えば以下のようにnuxt-linkを利用して自ページ内でアンカーリンクを実装してもうまく動作しません。

<template>
  <div>
    <nuxt-link to="#target">targetの位置へ</nuxt-link>
    
    <!-- アンカーリンク先を画面外にするため適当に表示 -->
    <h1 v-for="i in 50" :key="i">{{ i }}</h1>

    <div id="target">ここまでスクロールさせたい</div>
  </div>
</template>

aタグを使えば動作するのですが、せっかくならページリロードなしのnuxt-linkで統一したいですし、かといってその度に動作するかテストするのも大変です。さらに言えばアニメーションもつけてスムーズなスクロールにしたい…。

そこで、Vue.jsでスムーズにスクロールするアンカーリンクを実装する方法について説明したいと思います。

使用するnpmパッケージ

vue-scrolltoというnpmパッケージを利用します。

$ npm install --save vue-scrollto

pluginsに設定

パッケージをインストールしたあとはpluginsに設定し、どの画面でもvue-scrolltoを使えるようにします。

まず、vue-scrolltoパッケージをimportするpluginsファイルを作成します。

< plugins/vue-scrollto.js >

import Vue from 'vue'
import VueScrollTo from 'vue-scrollto'

Vue.use(VueScrollTo)

export default function vueScrollTo (context, inject) {
  inject('scrollTo', vueScrollTo.scrollTo)
}

作成したpluginsファイルをnuxt.config.jsに設定します。

< nuxt.config.js >

module.exports = {
…
  plugins: [
    '~/plugins/vue-scrollto'
  ],
…

これで設定は完了です。

アンカーリンクの実装

htmlタグ

一番最初の例で紹介したようにhtmlタグにアンカーリンクを設定してスクロールさせる場合は、v-scroll-toという要素に対象となるアンカーをセットします。

※ 内側のシングルクォーテーション('')を忘れないように注意!

< sample1.vue >

<template>
  <div>
    <nuxt-link v-scroll-to="'#target'" to>targetの位置へ</nuxt-link>

    <h1 v-for="i in 50" :key="i">{{ i }}</h1>

    <div id="target">ここまでスクロールさせたい</div>
  </div>
</template>

この状態で表示すると、以下のようにスムーズにスクロールします。

※ わかりやすくするため、duration: 1000でVueScrollToを設定しています。

clickイベント

リンクをクリックした時に他の処理をしてからアンカーへスクロールしたい場合はclickイベントを使います。

< sample2.vue >

<template>
  <div>
    <a href="javascript:void(0)" @click.prevent="onClick">targetの位置へ</a>

    <h1 v-for="i in 50" :key="i">{{ i }}</h1>

    <div id="target">ここまでスクロールさせたい</div>
  </div>
</template>

<script>
export default {
  methods: {
    onClick () {
      console.log('---ここで他の処理を行う---')

      this.$scrollTo('#target')
    }
  }
}
</script>

onClickメソッド内に書かれたthis.$scrollTo()によってアンカー位置までスクロールすることが可能です。

他画面からの遷移

これまでの例は自ページ内でアンカーリンクを実装する場合でしたが、他ページにアンカーリンクが存在してそこから遷移してくる場合もあると思います。

その場合は、画面描画時にURLパラメータからアンカーを取得し、this.$scrollTo()を使ってスクロールさせます。

< sample3.vue >

<template>
  <div>
    <h1 v-for="i in 50" :key="i">{{ i }}</h1>

    <div id="target">ここまでスクロールさせたい</div>
  </div>
</template>

<script>
export default {
  mounted () {
    const hash = this.$route.hash
    if (hash &amp;&amp; hash.match(/^#.+$/)) {
      this.$scrollTo(hash)
    }
  }
}
</script>

まとめ

vue-scrolltoは設定によってスクロール時間(duration)やスクロールアニメーション(easing)なども変更できるようなので、自分好みのアンカーリンクを実装してみてください!

参考

今回のコードはgithubで公開中なので参考にしてみてください!↓

https://github.com/hafilog/vue-sample/tree/master/components/pages/sample

投稿者: はふぃ

若手のWEBフロントエンジニア。最近はバレーボールにハマってます!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA