Slaveworx
Slaveworx

Reputation: 611

Vue Router navigate or scroll to anchors (# anchors)

I am struggling with vue-router not scrolling/navigating to anchor tags (ex: #anchor). I have read various solutions here on Stack Overflow, but none have worked so far.

Please find below the code I am using right now, which is not working:

main.js

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: "/docs/1.0/:title",
            component: Content,
            name: "docs"
        }
    ],
    scrollBehavior(to, from, savedPosition) {
        if (savedPosition) {
            return savedPosition;
        }
        if (to.hash) {
            return { selector: to.hash };
        }
        return { x: 0, y: 0 };
    },
});

Content.vue (Parent Component)

<template>
  <base-section
    v-for="entry in $store.state.entries"
    :key="entry.title"
    lang="lang-markup"
    :title="entry.title"
  >
    <template v-slot:sectionId>
      <div :id="slugify(entry.title)"></div>
    </template>

    <template v-if="entry.content" v-slot:content>
      <span v-html="entry.content"></span>
    </template>
    <template v-slot:examples>
      <div v-html="entry.examples"></div>
    </template>
    <template v-slot:code>
      {{ entry.code }}
    </template>
  </base-section>
</template>

SectionMenu.vue (Child Component)

<span v-for="item in $store.state.entries" :key="item.title">
  <router-link
    :to="{name:'docs', hash:'#'+slugify(item.title)}"
    class="mx-1 btn btn-primary"
  >{{ item.title }}</router-link>
</span>

I have also tried a different approach, but it also hasn't worked. This was the approach:

<button @click.prevent="navigate(item.title)">{{item.title}}</button>
navigate(route){
  this.$router.push({name:'docs', hash:'#'+this.slugify(route)})
},

Do you have any idea of what I am doing wrong?

PS: I am using VUE 3 (vue CLI 4.5.8)

Upvotes: 6

Views: 7977

Answers (1)

tony19
tony19

Reputation: 138316

In Vue Router 4, the format of the returned object from scrollBehavior() has changed from what it was in Vue Router 3. In particular, the object's selector property is now named el, as shown in the docs:

const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      // BEFORE:
      // return { selector: to.hash }

      return { el: to.hash }
    }
  },
})

demo

Upvotes: 9

Related Questions