Speichern und Verwenden der letzten bekannten Route in Vue

Avatar of Mateusz Rybczonek
Mateusz Rybczonek am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Es gibt Situationen, in denen es nützlich sein kann, eine Referenz auf die letzte Route zu behalten, die ein Benutzer besucht hat. Nehmen wir zum Beispiel an, wir arbeiten mit einem mehrstufigen Formular und der Benutzer schreitet von einem Schritt zum nächsten. Es wäre ideal, die Route dieses vorherigen Schritts zur Hand zu haben, damit wir wissen, wo der Benutzer aufgehört hat, falls er navigiert und später zurückkehrt, um das Formular später abzuschließen.

Wir werden behandeln, wie die letzte bekannte Route gespeichert und dann abgerufen wird, wenn wir sie benötigen. Wir arbeiten in diesem Beispiel mit Vue und verwenden vue-router für das Routing und localStorage, um die Informationen über die zuletzt besuchte Route zu speichern.

Hier ist ein Beispiel dafür, womit wir arbeiten werden

Zuerst skizzieren wir die Routenstruktur

Unser Beispiel hat insgesamt drei Routen

  • /home
  • /hello
  • /goodbye

Jede Route muss eine Namens-Eigenschaft zugewiesen bekommen, also fügen wir das unserer router.js-Datei hinzu

// router.js

import Vue from "vue";
import Router from "vue-router";
import Hello from "@/components/Hello";
import Goodbye from "@/components/Goodbye";

import {
  HELLO_URL,
  GOODBYE_URL
} from "@/consts";

Vue.use(Router);

const router = new Router({
  mode: "history",
  routes: [
    { path: "/", name: "home" },
    { path: HELLO_URL, name: "hello", component: Hello },
    { path: GOODBYE_URL, name: "goodbye", component: Goodbye }
  ]
});

export default router;

Als Nächstes gehen wir die Anforderungen durch

Wir wissen, dass die erste Anforderung darin besteht, die zuletzt besuchte Route in localStorage zu speichern. Und zweitens müssen wir sie abrufen können. Aber unter welchen Bedingungen soll die Route abgerufen und angewendet werden? Das gibt uns zwei zusätzliche Anforderungen.

  • der Benutzer die Hauptroute (/home) betritt, von ihr weg navigiert und dann zurückkehren möchte.
  • der Benutzer für eine bestimmte Zeit inaktiv war, die Sitzung abläuft und wir den Benutzer nach dem Neustart der Sitzung zur letzten Ansicht zurückführen möchten.

Diese vier Anforderungen müssen wir erfüllen, um mit der Weiterleitung fortzufahren.

Springen wir nun zum Code.

Anforderung 1: Speichern des Namens der letzten Route in localStorage

Wir möchten die Referenz auf unsere zuletzt besuchte Route in localStorage speichern. Wenn ein Benutzer beispielsweise auf /checkout ist und die Seite verlässt, möchten wir dies speichern, damit der Kauf später abgeschlossen werden kann.

Dazu wollen wir den Routennamen speichern, wenn der Benutzer eine neue Route betritt. Wir verwenden einen Navigations-Guard namens afterEach, der jedes Mal ausgelöst wird, wenn der Routenübergang abgeschlossen ist. Er liefert ein to-Objekt, das das Ziel- Route-Objekt ist. In diesem Hook können wir den Namen dieser Route extrahieren und mit einer setItem-Methode in localStorage speichern.

// router.js

const router = new Router( ... );

router.afterEach(to => {
  localStorage.setItem(LS_ROUTE_KEY, to.name);
});

...
export default router;

Anforderung 2: Abrufen des Namens der letzten Route aus localStorage und Weiterleitung

Nachdem nun der Name der letzten Route gespeichert ist, müssen wir ihn abrufen und eine Weiterleitung dazu auslösen, wenn er benötigt wird. Wir wollen prüfen, ob wir weiterleiten sollen, bevor wir eine neue Route betreten. Dazu verwenden wir einen weiteren Navigations-Guard namens beforeEach. Dieser Guard erhält drei Argumente

  • to: das Ziel-Route-Objekt
  • from: die aktuelle Route, von der navigiert wurde
  • next: die Funktion, die im Guard aufgerufen werden muss, um den Hook aufzulösen

In diesem Guard lesen wir den Namen der zuletzt besuchten Route mit einer localStorage.getItem()-Methode aus. Dann bestimmen wir, ob der Benutzer weitergeleitet werden soll. An diesem Punkt prüfen wir, ob die Zielroute (to) unsere Hauptroute (/home) ist und ob wir tatsächlich eine letzte Route in localStorage haben.

Wenn diese Bedingungen erfüllt sind, rufen wir die next-Methode auf, die den Namen der zuletzt besuchten Route enthält. Dies löst wiederum eine Weiterleitung zu dieser Route aus.

Wenn eine Bedingung fehlschlägt, rufen wir next ohne Argumente auf. Dies verschiebt den Benutzer zum nächsten Hook in der Pipeline und fährt mit dem normalen Routing ohne Weiterleitung fort.

// router.js

const router = new Router( ... );

router.beforeEach((to, from, next) => {
  const lastRouteName = localStorage.getItem(LS_ROUTE_KEY);
  
  const shouldRedirect = Boolean(
    to.name === "home" &&
    lastRouteName 
  );

  if (shouldRedirect) next({ name: lastRouteName });
  else next();
});

...
export default router;

Damit sind zwei von vier Anforderungen erfüllt! Wir fahren mit Anforderung Nummer drei fort.

Anforderung 3: Die Bedingung für den ersten Besuch

Nun müssen wir prüfen, ob der Benutzer die Hauptroute zum ersten Mal besucht (aus einer anderen Quelle kommt) oder von einer anderen Route innerhalb der Anwendung dorthin navigiert. Das können wir tun, indem wir ein Flag hinzufügen, das auf true gesetzt wird, wenn der Router erstellt wird, und es nach Abschluss des ersten Übergangs auf false setzen.

// router.js

const router = new Router( ... );

let isFirstTransition = true;

router.beforeEach((to, from, next) => {
  const lastRouteName = localStorage.getItem(LS_ROUTE_KEY);
  
  const shouldRedirect = Boolean(
    to.name === "home" &&
    && lastRouteName
    && isFirstTransition
  );

  if (shouldRedirect) next({ name: lastRouteName });
  else next();

  isFirstTransition = false;
});

...
export default router;

Okay, es gibt noch eine weitere Anforderung, die wir erfüllen müssen: Wir wollen den Benutzer zur letzten bekannten Route weiterleiten, wenn der Benutzer länger als ein bestimmter Zeitraum inaktiv war.

Anforderung 4: Die Bedingung für die Aktivitätszeit

Auch hier werden wir localStorage verwenden, um die Informationen über die zuletzt besuchte Route des Benutzers zu speichern.

Im beforeEach-Guard holen wir die Route aus localStorage und prüfen, ob die seit diesem Zeitpunkt vergangene Zeit innerhalb unserer Schwelle liegt (definiert durch hasBeenActiveRecently). Dann bestimmen wir in unserem shouldRedirect, ob eine Routenweiterleitung stattfinden soll oder nicht.

Wir müssen diese Informationen auch speichern, was wir im afterEach-Guard tun werden.

// router.js

const router = new Router( ... );

let isFirstTransition = true;

router.beforeEach((to, from, next) => {  
  const lastRouteName = localStorage.getItem(LS_ROUTE_KEY);
  const lastActivityAt = localStorage.getItem(LS_LAST_ACTIVITY_AT_KEY);

  const hasBeenActiveRecently = Boolean(
    lastActivityAt && Date.now() - Number(lastActivityAt) < MAX_TIME_TO_RETURN
  );

  const shouldRedirect = Boolean(
    to.name === "home" &&
    && lastRouteName
    && isFirstTransition
    && hasBeenActiveRecently
  );

  if (shouldRedirect) next({ name: lastRouteName });
  else next();

  isFirstTransition = false;
});

router.afterEach(to => {
  localStorage.setItem(LS_ROUTE_KEY, to.name);
  localStorage.setItem(LS_LAST_ACTIVITY_AT_KEY, Date.now());
});

...
export default router;

Wir haben die Anforderungen erfüllt!

Das ist alles! Wir haben alle vier Anforderungen behandelt, nämlich

  • Wir speichern die zuletzt besuchte Route in localStorage
  • Wir haben eine Methode, um die zuletzt besuchte Route aus localStorage abzurufen
  • Wir leiten einen Benutzer zur Hauptroute zurück, wenn er die Anwendung bei einem erstmaligen Besuch betritt
  • Wir bieten dem Benutzer eine Weiterleitung zur zuletzt bekannten Route innerhalb eines bestimmten Zeitraums

Natürlich können wir dies weiter ausbauen, indem wir der App mehr Komplexität und der Variable shouldRedirect neue Bedingungen hinzufügen, aber dies gibt uns mehr als genug, um zu verstehen, wie wir die zuletzt besuchte Route persistent halten und bei Bedarf abrufen können.