Why doesn't scrollIntoView work in Vue 3 even though I'm able to get a reference to the element that I'm trying to scroll to

Viewed 4380

I have a Vue 3 component that I'm trying to setup as my navigation for a single page app. When the user clicks on an item I'd like for the page to scroll to the element that contains the content for that section.

The strange thing is that I'm able to get a reference to the div using document.querySelector. I'm able to log the div to the consol however when I try to call scrollIntoView on the div it doesn't do anything unless I wrap the element.scrollIntoView in a setTimeout function.

I'm sure this has something to do with the Vue component life cycle. I've tried wrapping my code in the onMounted function and that only makes my scrollPageTo function fall out of scope.

<template>
    <div id="navigation-view" class="navigation-bar bg-gradient-to-tr w-full mx-auto flex items-start py-4">
        <div class="w-full mx-auto text-right">
                <nav>
                    <a class="top-nav-item" href="#" v-on:click="scrollPageTo('home-view')">
                        <i class="fa fa-home fa-lg"></i> Home
                    </a>

                    <a class="top-nav-item" href="#" v-on:click="scrollPageTo('hello-view')">
                        <i class="fa fa-hands-helping fa-lg"></i> Hello
                    </a>

                    <a class="top-nav-item" href="#" v-on:click="scrollPageTo('contact-view')">
                        <i class="fa fa-envelope fa-lg"></i> Contact
                    </a>
                </nav>
        </div>
    </div>
    <div class="logo">
        <img src="/assets/img/615io-logo-wbg.png" alt="615io logo">
    </div>
</template>
<script lang="ts">
import {defineComponent, onMounted} from "vue";
export default defineComponent({
    setup() {

        const scrollPageTo = (navEl) => {
            console.log(`#${navEl}`);
            let element = document.querySelector(`#${navEl}`);
            console.log(element);
            element.scrollIntoView({behavior: 'smooth'});
        }

        return {
            scrollPageTo,
        }


    }
});
</script>
1 Answers

Add prevent modifier to the click event because this modifier prevent the default behavior which is the navigation to #:

v-on:click.prevent="scrollPageTo('home-view')"

LIVE DEMO

Related