So erstellen Sie Anker-Tags mit Vue Router

Lesezeit: 5 Minuten

Ich erstelle eine kleine Vue webapp, ich möchte darin ein Anker-Tag erstellen.

ich habe eine gegeben id zu einem von div Ich wollte Anker-Tags wie diese haben:

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

Und hier ist meine Router-Konfiguration:

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

Aber mit diesem Anker funktionieren die Tags manchmal und manchmal nicht. Habe ich da etwas übersehen?

So erstellen Sie Anker Tags mit Vue Router
Mani

Ich glaube, Sie fragen, ob Sie direkt zu einem bestimmten Bereich der Seite springen möchten, indem Sie zu einem Anker-Tag wie navigieren #section-3 innerhalb der Seite.

Damit dies funktioniert, müssen Sie Ihre scrollBehavior-Funktion wie folgt ändern:

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: "https://stackoverflow.com/", component: abcView},
        // your routes
    ]
});

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

Ich habe versucht, ein jsFiddle-Beispiel zu erstellen, aber es funktioniert nicht wegen mode:'history'. Wenn Sie den Code kopieren und lokal ausführen, sehen Sie, wie er funktioniert: https://jsfiddle.net/mani04/gucLhzaL/

Durch die Rückkehr {selector: to.hash} (oder {el: to.hash} in Vue 3) in scrollBehavior übergeben Sie den Anker-Tag-Hash an die nächste Route, die zum entsprechenden Abschnitt navigiert (markiert mit id) auf dieser Strecke.

  • Funktioniert das nur im Verlaufsmodus? Ich kann es nicht zum Laufen bringen, aber ich bin nicht im Verlaufsmodus

    – rückläufig

    2. Dezember ’16 um 20:53

  • Ja das Scroll-Verhalten Seite erwähnt dies deutlich. Der Grund dafür ist, dass Sie die Hash-ID bereits an den Routerstatus gebunden haben. Es ist nicht möglich, einen zweiten Hash zu verwenden, um die Seitenposition zu identifizieren (zum Anker scrollen). Eine andere Möglichkeit ist, a . zu übergeben query Parameter in der Route und verwenden Sie dann einfaches altes Javascript, um an die richtige Stelle innerhalb der Zielseite zu scrollen. Ich habe kein funktionierendes Beispiel, das ich zeigen kann, aber ich glaube, es ist machbar, wenn wir etwas Zeit damit verbringen.

    – Mani

    3. Dez. ’16 um 3:00

  • Oh, ja, es wird deutlich erwähnt. Ich schwöre, dass ich einen blinden Fleck für fette Notizen habe. Danke

    – rückläufig

    4. Dezember ’16 um 5:42

  • Wichtiger Hinweis für Vue 3-Benutzer, x und y auch geändert zu left und top next.router.vuejs.org/guide/advanced/scroll-behavior.html

    – V. Rubinetti

    1. Okt ’21 um 15:55

So erstellen Sie Anker Tags mit Vue Router
Adam Reis

Für mich das {selector: to.hash} Lösung weigerte sich nur, mit vue-router 4.0.0 zu arbeiten. Der folgende Ansatz funktionierte und ermöglichte auch ein flüssiges Scrollen.

Der Timeout von 500ms ist dazu da, das Laden der Seite zu ermöglichen, da ich festgestellt habe, dass ansonsten ein flüssiges Scrollen nicht an die richtige Position gescrollt würde (weil die Seite noch geladen wurde).

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}
}

  • Für Vue 3 return { el: to.hash } anstatt return { selector: to.hash } funktioniert.

    – rits

    13. Januar ’21 um 21:43

  • Das scheint tatsächlich zu funktionieren, schade, dass es nicht dokumentiert ist!

    – Adam Reis

    14. Januar ’21 um 23:25

Ich bin auch gerade auf dieses Problem gestoßen und dachte, es gibt ein wenig Platz, um den Seitentausch zu optimieren. In meinem Fall möchte ich einen fließenden Übergang machen, anstatt “herumzuspringen”. Ich habe in jQuery bereits als Alias ​​für $ benötigt.

Hier ist mein Router-Setup für die reibungslose Animation. Sie können die Linien gerne entsprechend Ihren Bedürfnissen anpassen. Dieser Code könnte sauberer gemacht werden, sollte aber fein genug sein, um Ihnen die Arbeitsidee zu zeigen.

// 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);
       }
    }
})

Nebenfrage meinerseits: Müssen wir etwas zurückgeben? Ich habe keine Probleme mit oder ohne Rückkehr, da die jQuery-Animation das Scrollen der Seite übernimmt.

Grüße Gkiokan

1642054564 590 So erstellen Sie Anker Tags mit Vue Router
AndrewRECHTS

Wenn Sie animiertes scrollTo erstellen müssen, verwende ich das Paket vue-scrollTo: Es ist sehr einfach einzurichten.

Beispiele mit Dokumenten und Code finden Sie hier: https://github.com/rigor789/vue-scrollto/

So erstellen Sie Anker Tags mit Vue Router
ivqonsanada

Ich habe die Antwort von Adam Reis ausprobiert, sie funktioniert. Aber im Vergleich zum Original finde ich es nicht so gut return {selector: to.hash} wenn Sie die Seite aktualisieren. Also habe ich einen anderen Ansatz versucht, indem ich Promise verwendet habe. Es funktioniert genauso wie das Original.

Hier ist der Code:

function scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  }

  if (to.hash) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ selector: to.hash })
      }, 300)
    })
  }

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ x: 0, y: 0 })
    }, 300)
  })
}

Ich denke, das Problem ist, dass die Hash-Route ausgeführt wird, bevor die Seite vollständig geladen ist. Deshalb tut es nichts, weil noch kein Element mit der ID angezeigt wird. Aber ich weiß nicht warum, wenn ich die Seite aktualisiere, funktioniert es großartig. Das ist jedenfalls meine Lösung. Ich hoffe, es hilft jedem Neuling.

Notiz:

  • Dieser Code funktioniert gut beim Navigieren zu einer anderen Seite oder derselben Seite. Passen Sie das Timeout nach Bedarf an.
  • Für eine reibungslose Navigation verwende ich nur CSS. Auf dem Wurzelelement / Element, das die Schriftrolle hat, können Sie hinzufügen scroll-behavior: smooth; um es glatt zu machen, wie auf erwähnt MDN.
  • Ich habe vue-router 3.5.1 verwendet, da ich immer noch Vue 2.x verwende. Wenn Sie Vue 3 verwenden, können Sie den Code wie in der Antwort von Adam Reis beschrieben anpassen.

.

482580cookie-checkSo erstellen Sie Anker-Tags mit Vue Router

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy