FORSMILE
EN
VUE2020/09/03

[VUE.JS]Vue Router使用時にページ内アンカーにリンクする方法

Vue.jsを使用しているプロジェクトで、ページ内のアンカーポイントにリンクするボタンの実装をしました。

ブログ一覧へ / Back to Blog

Vue.jsを使用しているプロジェクトで、ページ内のアンカーポイントにリンクするボタンの実装をしました。

html
<a href="#xxxx">テストリンク</a>

でいいのかと思ったら、上記で実装した場合、アンカーに飛ぶには飛ぶのですが、ページのURLが/#xxxxになってしまいました。

リロードするまでは、正常に動作していたんですが、リロードしたら真っ白に!

Vue Routerの設定によっては、そもそもアンカーが動作しなかったりする場合もあります。

scrollIntoViewでアンカーポイントまでスクロールする

javascript
// button part
<a class="btn-primary" @click="scrollToAnchorPoint('testBlock')">
    Scroll Test
</a>

// anchor point
<div ref="testBlock">
    In page anchor point
</div>

//  methods
<script>
export default{
    ...
    methods: {
        scrollToAnchorPoint(refName) {
            const el = this.$refs[refName]
            el.scrollIntoView({ behavior: 'smooth'})
        }
    }
}
</script>

Vue.jsでDOM要素にアクセスする場合、refで名前を付けます。

他のページからアンカーポイントにリンクする

今度は外部ページからアンカーポイントに遷移させたい場合の方法です。

routerlinkにhashを付ける方法

css
//not bind
<router-link to="/testpage#testBlock">
    Link to TestBlock in TestPage
</router-link>

//use bind
<router-link
    :to="{
        name: 'testPage',
        hash: '#testBlock'
    }"
>
    Link to TestBlock in TestPage
</router-link>

hashからアンカーポイントまでスクロール

URLで受け取ったハッシュから該当のポイントまでスクロールさせます。

javascript
export default{
    data: function(){
        return {
            hash: this.$route.hash,
        }
    },
    mounted() {
        this.$nextTick(function () {
            if (this.hash) {
                const refName = this.hash.replace('#', '')
                this.scrollToAnchorPoint(refName)
            }
        })
    },
    methods: {
        scrollToAnchorPoint(refName) {
            const el = this.$refs[refName]
            el.scrollIntoView({ behavior: 'smooth' })
        }
    }
}

this.$route.hashでハッシュを取得しています。

DOMが生成された後にscrollToAnchorPointを実行したいので、

this.$nextTick()を使用して読み込み完了時に実行しています。

画面で画像(image等)を多用している場合

遷移した先で画像などを多用している場合は、DOM生成時に位置ずれが発生し正確な場所にスクロールしません。

text
<div style="height: 400px;">
    <img src="/image/test.png">
</div>

注意としては画像自体の幅高さではなく、外側の要素に対して高さを指定することです。

とはいえ、全部に高さを指定するのが不可能な場合もあると思います。

javascript
mounted() {
    this.$nextTick(function () {
        if (this.hash) {
            const refName = this.hash.replace('#', '')
            setTimeout(() => {
                this.scrollToAnchorPoint(refName)
            }, 100)
        }
    })
},

5分で終わると思ってたアンカーポイントの実装に、以外と苦労したので記事にしてみました。

VUE.JSおすすめの書籍

書籍は読む方だと思いますが、やはり現場で実装するとより深く学べるのを実感します。

逆に実装中心だと、より良いコーディングを考えることができなくなるので書籍もあらためて読むことをおすすめします。

JavaScript、Vue.jsの知識がある程度ある方向け

📦
Amazon で関連書籍・ツールを検索
Vue.js フロントエンド入門
Amazonで探す →(アソシエイトリンク)