Vue.js scroll to top of page for same route

vue.jsVue Router

vue.js Problem Overview


I can set scrolling behaviour to Vue.js Router like this:

const router = new Router({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'index',
            component: Main
        },
        {
            path: '/some-path',
            name: 'some-path',
            component: SomePath
        }
    ],
    scrollBehavior() {
        return {x: 0, y: 0}
    }
})

This works perfectly when you click on the link with some page which is not current. When I click on the link which is already rendered, i.e. in the footer, nothing happens. Vue Router assumes there is no state transition. What is the preferred way to scroll up in this case?

vue.js Solutions


Solution 1 - vue.js

You can't do this through vue-router, but you can add a scroll-to-top method to every router-link.

Just create a method like this:

methods: { 
  scrollToTop() {
    window.scrollTo(0,0);
  }
}

Add it to the link:

<router-link @click.native="$scrollToTop">

If you want to use it outside of your footer too, it's better to add it to the Vue prototype

Vue.prototype.$scrollToTop = () => window.scrollTo(0,0)

It's not a 100% solution but it's the simplest one

Solution 2 - vue.js

I couldn't get any of the above solutions working, and it was really frustrating.

What ended up working for me was the below:

    const router = new Router({
        mode: 'history',
        routes: [...],
        scrollBehavior() {
            document.getElementById('app').scrollIntoView({ behavior: 'smooth' });
        }
    })

I mount my VueJs app to #app so I can be certain it is present and is available for selection.

Solution 3 - vue.js

You could make use of behavior: smooth:

    moveTo () {
      let to = this.moveToDown
        ? this.$refs.description.offsetTop - 60
        : 0

      window.scroll({
        top: to,
        left: 0,
        behavior: 'smooth'
      })

      this.moveToDown = !this.moveToDown
    }

Solution 4 - vue.js

The best solution I've found for this is: https://router.vuejs.org/guide/advanced/scroll-behavior.html

Specifically:

    const router = new VueRouter({
      routes: [...],
      scrollBehavior (to, from, savedPosition) {
        return { x: 0, y: 0 }
      }
    })

Solution 5 - vue.js

Expanding on the answer from Vitaly Migunov, you can instead add directly from the router a scrollTo method to the window object. This way you won't need to add the function to every router link.

    const router = new Router({
      mode: 'history',
      routes: [...],
      scrollBehavior() {
        window.scrollTo(0,0);
      }
    })

Solution 6 - vue.js

Use refs for scroll to certain section

    <template>
      <body>
        <div ref="section">
          // Your content section
        </div>
      </body>
    </template>
        
    export default class MyPage extends Vue {
      $refs!: {
        section: HTMLFormElement;
      };
    
      scrollToTop() {
        this.$refs.section.scrollTo(0, 0);
      }
    }

Solution 7 - vue.js

Basically, I think you want to scroll to the top of the page, unless an internal page location is specified (e.g. www.example.com/home#blah). All of the answers so far would ignore this location parameter, and just scroll to the top anyway.

    scrollBehavior(to, from, savedPosition) {
        //If there is no hash parameter when we change vue, scroll to top of page
        if (!to.hash) {
          return { x: 0, y: 0 }
        }
      }

We can check if there is a location parameter using to.hash, then only scroll to the top if no hash location is present.

Solution 8 - vue.js

Vue Js have inbuilt support for scrolling if the browser supports history.pushState.

It is very easy to configure, Just provide the scrollBehavior function, when creating Vue router instance like below:

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // page scroll to top for all route navigations
    return { x: 0, y: 0 }
  }
})

For more options and detail about Vue Scroll Behavior click here

Solution 9 - vue.js

Use this nice component: https://www.npmjs.com/package/vue-backtotop

<back-to-top text="Back to top"></back-to-top>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkuceramView Question on Stackoverflow
Solution 1 - vue.jsVitaly MigunovView Answer on Stackoverflow
Solution 2 - vue.jsSweet Chilly PhillyView Answer on Stackoverflow
Solution 3 - vue.jsPJ.WandersonView Answer on Stackoverflow
Solution 4 - vue.jsBen ComroeView Answer on Stackoverflow
Solution 5 - vue.jspaddyfieldsView Answer on Stackoverflow
Solution 6 - vue.jsJXLaiView Answer on Stackoverflow
Solution 7 - vue.jsF_SO_KView Answer on Stackoverflow
Solution 8 - vue.jsAbhayView Answer on Stackoverflow
Solution 9 - vue.jsSinan EldemView Answer on Stackoverflow