FORSMILE
JA
VUE2020/09/03

[VUE.JS] How to link to in-page anchors when using Vue Router

In a project using Vue.js, I implemented a button that links to an anchor point within the page.

Back to Blog

In a project using Vue.js, I implemented a button that links to an anchor point within the page.

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

I thought this would be fine, but when I implemented it this way, it did jump to the anchor, but the page URL changed to `/#xxxx`.

It worked normally until I reloaded, but upon reloading, the page went completely blank!

Depending on your Vue Router configuration, anchors might not even work at all.

SCROLL TO ANCHOR POINT WITH 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>

When accessing DOM elements in Vue.js, you assign them a name using `ref`.

LINKING TO AN ANCHOR POINT FROM ANOTHER PAGE

Next, here's how to navigate to an anchor point from an external page.

How to add a hash to router-link

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>

Scrolling to an anchor point from a hash

This scrolls to the corresponding point using the hash received in the 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' })
        }
    }
}

The hash is obtained using `this.$route.hash`.

Since we want to execute `scrollToAnchorPoint` after the DOM has been generated,

we are using `this.$nextTick()` to execute it when the loading is complete.

WHEN USING MANY IMAGES (ETC.) ON THE PAGE

If the destination page heavily uses images or similar elements, a position misalignment can occur during DOM generation, preventing accurate scrolling to the intended location.

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

The important thing to note is to specify the height for the outer element, not for the image itself.

However, it might not always be possible to specify a height for every element.

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

I struggled more than expected with implementing anchor points, which I thought would only take 5 minutes, so I decided to write an article about it.

RECOMMENDED VUE.JS BOOKS

While I do read books, I really feel that hands-on implementation in a real-world setting allows for deeper learning.

Conversely, focusing solely on implementation can make it harder to think about better coding practices, so I recommend revisiting books as well.

For those with some knowledge of JavaScript and Vue.js

📦
Amazon で関連書籍・ツールを検索
Vue.js frontend development book
Amazonで探す →(アソシエイトリンク)