Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create anchor tags with Vue Router

I am creating a small Vue webapp, I want to create an anchor tag in this.

I have given an id to one of the div I wanted to have anchor tags like this:

<div id="for-home">
   ....
</div>

And here is my router configuration:

export default new Router({
  abstract: true,
  mode: 'history',
  scrollBehavior: () => ({ y: 0 }),
  routes: [
    { path: '/', component: abcView}
  ]
})

But with this anchor tags are sometimes working and sometimes not working, Have I missed something in this?

like image 990
Saurabh Avatar asked Oct 31 '16 12:10

Saurabh


People also ask

What is meta in route Vue?

Sometimes, you might want to attach arbitrary information to routes like transition names, who can access the route, etc. This can be achieved through the meta property which accepts an object of properties and can be accessed on the route location and navigation guards.


4 Answers

I believe you are asking about jumping directly to a particular area of page, by navigating to an anchor tag like #section-3 within the page.

For this to work, you need to modify your scrollBehavior function as follows:

new VueRouter({
    mode: 'history',
    scrollBehavior: function(to, from, savedPosition) {
        if (to.hash) {
            return {selector: to.hash}
            //Or for Vue 3:
            //return {el: to.hash}
        } else {
            return { x: 0, y: 0 }
        }
    },
    routes: [
        {path: '/', component: abcView},
        // your routes
    ]
});

Ref: https://router.vuejs.org/guide/advanced/scroll-behavior.html#async-scrolling

I attempted creating a jsFiddle example but it is not working because of mode:'history'. If you copy the code and run locally, you will see how it works: https://jsfiddle.net/mani04/gucLhzaL/

By returning {selector: to.hash} (or {el: to.hash} in Vue 3) in scrollBehavior, you will pass the anchor tag hash to the next route, which will navigate to the relevant section (marked using id) in that route.

like image 187
Mani Avatar answered Oct 17 '22 04:10

Mani


For me the {selector: to.hash} solution just refused to work with vue-router 4.0.0. The following approach worked and also enabled smooth scrolling.

The timeout of 500ms is there to allow the page to load, because I found that otherwise smooth scrolling would not scroll to the correct position (because the page was still loading).

const scrollBehavior = (to, from, savedPosition) => {
  if (to.hash) {
    setTimeout(() => {
      const element = document.getElementById(to.hash.replace(/#/, ''))
      if (element && element.scrollIntoView) {
        element.scrollIntoView({block: 'end', behavior: 'smooth'})
      }
    }, 500)

    //NOTE: This doesn't work for Vue 3
    //return {selector: to.hash}

    //This does
    return {el: to.hash};
  }
  else if (savedPosition) {
    return savedPosition
  }
  return {top: 0}
}
like image 21
Adam Reis Avatar answered Oct 17 '22 02:10

Adam Reis


I have just came across this problem too and I thought there is a little space to optimize the page swap. In my case I'd like to make a smooth transition instead of "jumping arround". I've already required in jQuery as alias for $.

Here is my Router Setup for the smooth animation, feel free to modify the lines to your needs accordingly. This code could been made cleaner but should be fine enough to show you the working idea.

// Register Router and Paths
const router = new VueRouter({
    mode: 'history',
    routes : [
        { path: '/aboutme/', component: index, name:'me.index'},
        { path: '/aboutme/cv', component: cv, name:'me.cv' }
    ],

    // Build smooth transition logic with $
    scrollBehavior (to, from, savedPosition) {
       if (to.hash) {
          return $('html,body').stop().animate({scrollTop: $(to.hash).offset().top }, 1000);
       } else {
          return $('html,body').stop().animate({scrollTop: 0 }, 500);
       }
    }
})

Side Question on my side: Do we have to return anything? I don't have any trouble with or without returning due the jQuery Animation is handling the page scroll.

regards Gkiokan

like image 2
Gkiokan Avatar answered Oct 17 '22 04:10

Gkiokan


If you need to make animated scrollTo I use package vue-scrollTo: it's very easy to setup.

Examples with docs and code can be found here: https://github.com/rigor789/vue-scrollto/

like image 2
AndrewRIGHT Avatar answered Oct 17 '22 02:10

AndrewRIGHT