aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webentwicklung

Vue Router: Routen, Params und Navigation Guards

Vue Router ist die offizielle Lösung für Single-Page-Routing (SPA) in Vue-3-Apps: Sie ändert die URL ohne kompletten Reload, rendert die richtige Komponente und arbeitet korrekt mit den Vor- und Zurück-Buttons des Browsers. Dieser Leitfaden behandelt Routendefinitionen, dynamische Params, programmatische Navigation und die Navigation Guards für die Zugriffskontrolle anhand echter Beispiele. Alles hier bezieht sich auf Vue Router 4 (die mit Vue 3 verwendete Version).

Installation und eine einfache Routendefinition

Installiere das Paket und erstelle eine Router-Instanz. createRouter erhält einen history-Modus und ein routes-Array:

npm install vue-router@4
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  { path: '/', name: 'home', component: Home },
  { path: '/about', name: 'about', component: About },
]

export const router = createRouter({
  history: createWebHistory(),
  routes,
})

Binde den Router anschließend in die App ein:

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { router } from './router'

createApp(App).use(router).mount('#app')

<router-view> bestimmt, wo die passende Komponente gerendert wird, und Links erstellst du mit <router-link>, damit kein kompletter Seiten-Reload erfolgt:

<router-link to="/">Startseite</router-link>
<router-link :to="{ name: 'about' }">Über uns</router-link>
<router-view />

Routen einen Namen zu geben ist eine gute Angewohnheit: Selbst wenn sich die URL-Struktur ändert, funktionieren mit name gebaute Links weiterhin.

history-Modus: Web History oder Hash?

Es gibt zwei gängige Optionen. createWebHistory() erzeugt saubere URLs (/about), verlangt aber, dass dein Server jeden unbekannten Pfad auf index.html umleitet; sonst bekommst du beim Reload einen 404. createWebHashHistory() fügt der URL ein # hinzu (/#/about) und braucht keine Serverkonfiguration — praktisch fürs statische Hosting, aber ästhetisch und für SEO schwächer. Die meisten modernen Projekte bevorzugen Web History und ergänzen eine Fallback-Regel auf dem Server.

Dynamische Params

Segmente in einem Pfad, die mit : beginnen, sind dynamische Params. Zum Beispiel eine Detailseite:

const routes = [
  { path: '/users/:id', name: 'user', component: UserDetail },
]

In der Komponente liest du den Param mit useRoute(). Eine typische Verwendung mit der Composition API sieht so aus:

<script setup>
import { useRoute } from 'vue-router'
import { watch, ref } from 'vue'

const route = useRoute()
const user = ref(null)

async function load(id) {
  user.value = await fetch(`/api/users/${id}`).then(r => r.json())
}

load(route.params.id)

// Param-Änderungen beobachten, wenn dieselbe Komponente wiederverwendet wird
watch(() => route.params.id, (id) => load(id))
</script>

Hier gibt es einen kritischen Punkt: Wenn der Benutzer von /users/1 zu /users/2 wechselt, verwendet Vue dieselbe Komponenteninstanz wieder, die Komponente wird also nicht neu erstellt. Deshalb musst du route.params.id mit watch beobachten, um die Daten neu zu laden. Möchtest du den Param lieber als Prop erhalten, setze props: true auf der Route; deine Komponente erhält id dann als gewöhnliche Prop und wird leichter testbar.

Nutze :id? für einen optionalen Param und das Muster /:pathMatch(.*)*, um mehrere Segmente abzufangen; Letzteres wird üblicherweise für eine 404-Seite verwendet.

Programmatische Navigation und Query-Params

Um aus dem Code zu navigieren, nachdem ein Formular abgeschickt oder eine Aktion abgeschlossen wurde, verwende useRouter():

<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

function goToUser(id) {
  router.push({ name: 'user', params: { id } })
}

function search(term) {
  router.push({ path: '/search', query: { q: term } })
}
</script>

Query-Params (?q=...) liest du über route.query. Verwende router.replace(), um den aktuellen Schritt zu ändern, ohne einen neuen History-Eintrag zu hinterlassen, und router.back(), um zurückzugehen.

Navigation Guards: Zugriffskontrolle

Guards erlauben es, vor einem Übergang einzugreifen und ihn zuzulassen, umzuleiten oder abzubrechen — das zentrale Werkzeug für die Authentifizierung. Der häufigste globale Guard ist beforeEach:

router.beforeEach((to, from) => {
  const isAuth = !!localStorage.getItem('token')
  if (to.meta.requiresAuth && !isAuth) {
    // Ein Location-Objekt zurückzugeben leitet den Übergang dorthin um
    return { name: 'login', query: { redirect: to.fullPath } }
  }
  // true oder nichts zurückzugeben lässt den Übergang zu
})

Der moderne Stil in Vue Router 4 ist, einen Wert zurückzugeben, statt next() aufzurufen: false bricht den Übergang ab, ein Location-Objekt leitet um, und alles andere (oder undefined) lässt ihn zu. Welche Routen geschützt sind, markierst du mit dem Feld meta in der Routendefinition:

{
  path: '/dashboard',
  name: 'dashboard',
  component: Dashboard,
  meta: { requiresAuth: true },
}

Musst du nur eine einzelne Route schützen, verwende den routeneigenen beforeEnter-Guard. Innerhalb einer Komponente erlaubt dir onBeforeRouteLeave Prüfungen wie „Du hast nicht gespeicherte Änderungen, möchtest du wirklich verlassen?"

Lazy Loading und verschachtelte Routen

In großen Apps verlangsamt das Vorabladen jeder View das erste Öffnen. Indem du die Komponente als dynamisches import() übergibst, erhältst du Code-Splitting auf Routenebene; dieser Chunk wird erst heruntergeladen, wenn die Route besucht wird:

const routes = [
  { path: '/about', component: () => import('../views/About.vue') },
]

Für verschachtelte Layouts (zum Beispiel Tabs in einem Benutzerprofil) verwende children und platziere ein zweites <router-view> im Template der übergeordneten Komponente:

{
  path: '/users/:id',
  component: UserLayout,
  children: [
    { path: '', component: UserOverview },
    { path: 'posts', component: UserPosts },
  ],
}

Häufige Fragen

Warum wird meine Seite nicht aktualisiert, wenn sich der Param ändert?

Weil Vue Router dieselbe Komponente wiederverwendet, statt sie neu zu erstellen. Beobachte entweder route.params mit watch und lade die Daten neu, oder gib der Komponente einen eindeutigen :key, um einen Remount zu erzwingen.

Warum bekomme ich beim Neuladen der Seite einen 404?

Im Web-History-Modus kennt dein Server Pfade wie /about nicht. Konfiguriere den Server so, dass er alle nicht passenden Anfragen auf index.html umleitet (der SPA-Fallback); ist das nicht möglich, verwende stattdessen Hash History.

Soll ich next() oder return in beforeEach verwenden?

In Vue Router 4 wird empfohlen, einen Wert zurückzugeben; das ist sauberer und weniger fehleranfällig. next() funktioniert weiterhin, aber mische die beiden nicht im selben Guard, sonst kann der Übergang zweimal verarbeitet werden.

Ist das Routing in deinem Vue-Projekt unübersichtlich geworden? Lass uns deine Routenstruktur, deine Guards und das Code-Splitting gemeinsam durchgehen und daraus eine solide Architektur machen. Kontaktiere mich und wir bauen eine Lösung, die zu deinen Anforderungen passt.

Bu kategorideki tüm yazılar →

Devamı için