こんにちは、”はふぃ”です。
アンカーリンクとは、リンクしたい場所にアンカー(目印)を置いてページ内ジャンプをするための機能のことで、htmlでは飛び先の要素にid=”アンカー名”、リンクにhref=”#アンカー名”を設定することで実装できます。
例えば以下のように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 && hash.match(/^#.+$/)) {
this.$scrollTo(hash)
}
}
}
</script>

まとめ
vue-scrolltoは設定によってスクロール時間(duration)やスクロールアニメーション(easing)なども変更できるようなので、自分好みのアンカーリンクを実装してみてください!
参考
今回のコードはgithubで公開中なので参考にしてみてください!↓
https://github.com/hafilog/vue-sample/tree/master/components/pages/sample