Vue Router
Vue Router ist die offizielle Routing-Lösung für Vue.js Single-Page-Applications.
Es ermöglicht Navigation zwischen Views ohne vollständigen Page-Reload.
npm install vue-router@4Grundkonfiguration
Abschnitt betitelt „Grundkonfiguration“import { createRouter, createWebHistory } from 'vue-router'import HomeView from '@/views/HomeView.vue'import AboutView from '@/views/AboutView.vue'
const routes = [ { path: '/', component: HomeView }, { path: '/about', component: AboutView }]
const router = createRouter({ history: createWebHistory(), routes})
export default routerRouter einbinden
Abschnitt betitelt „Router einbinden“import { createApp } from 'vue'import App from './App.vue'import router from './router'
const app = createApp(App)app.use(router)app.mount('#app')<template> <nav> <RouterLink to="/">Home</RouterLink> <RouterLink to="/about">About</RouterLink> </nav>
<RouterView /> <!-- Hier wird die aktuelle Route gerendert --></template>RouterLink
Abschnitt betitelt „RouterLink“RouterLink erstellt Links für die Navigation ohne Page-Reload:
<template> <!-- Einfacher Link --> <RouterLink to="/about">About</RouterLink>
<!-- Mit Objekt-Syntax --> <RouterLink :to="{ path: '/users' }">Users</RouterLink>
<!-- Mit Namen --> <RouterLink :to="{ name: 'user', params: { id: 123 } }"> User 123 </RouterLink>
<!-- Aktiv-Klassen --> <RouterLink to="/about" active-class="font-bold" exact-active-class="text-blue"> About </RouterLink>
<!-- Als anderes Element rendern --> <RouterLink to="/about" custom v-slot="{ navigate, isActive }"> <button @click="navigate" :class="{ active: isActive }">About</button> </RouterLink></template>Dynamische Routen
Abschnitt betitelt „Dynamische Routen“const routes = [ // Dynamischer Parameter mit : { path: '/users/:id', component: UserView },
// Mehrere Parameter { path: '/users/:userId/posts/:postId', component: PostView },
// Optionaler Parameter mit ? { path: '/users/:id?', component: UsersView },
// Catch-all / 404 { path: '/:pathMatch(.*)*', component: NotFoundView }]Route-Parameter auslesen
Abschnitt betitelt „Route-Parameter auslesen“<script setup>import { useRoute } from 'vue-router'import { computed } from 'vue'
const route = useRoute()
// Reaktiver Zugriffconst userId = computed(() => route.params.id)
// Query-Parameterconst page = computed(() => route.query.page)</script>
<template> <p>User ID: {{ route.params.id }}</p> <p>Seite: {{ route.query.page }}</p></template><script>export default { computed: { userId() { return this.$route.params.id } }, watch: { '$route.params.id'(newId) { // Auf Änderung reagieren this.fetchUser(newId) } }}</script>Params vs Query
Abschnitt betitelt „Params vs Query“/users/123?sort=name&order=asc ─── ────────────────── params query- Teil der URL-Struktur
- Für Ressourcen-IDs
- Definiert in Route-Config
{ path: '/users/:id' }// → route.params.id- Nach dem
? - Für Filter, Sortierung, Pagination
- Frei verwendbar
<RouterLink :to="{ path: '/users', query: { sort: 'name', page: 2 }}">Programmatische Navigation
Abschnitt betitelt „Programmatische Navigation“<script setup>import { useRouter } from 'vue-router'
const router = useRouter()
function goToUser(id) { // String router.push('/users/' + id)
// Objekt mit path router.push({ path: `/users/${id}` })
// Objekt mit name router.push({ name: 'user', params: { id } })
// Mit Query router.push({ path: '/users', query: { page: 2 } })}
function goBack() { router.back() // oder router.go(-1)}
function replaceRoute() { router.replace('/login') // Kein History-Eintrag}</script>Benannte Routen
Abschnitt betitelt „Benannte Routen“const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/users/:id', name: 'user', component: UserView }]<template> <!-- Verwendung mit name statt path --> <RouterLink :to="{ name: 'home' }">Home</RouterLink>
<RouterLink :to="{ name: 'user', params: { id: 123 } }"> User 123 </RouterLink></template>Verschachtelte Routen
Abschnitt betitelt „Verschachtelte Routen“const routes = [ { path: '/users', component: UsersLayout, children: [ { path: '', component: UsersList }, // /users { path: ':id', component: UserDetail }, // /users/123 { path: ':id/edit', component: UserEdit } // /users/123/edit ] }]<template> <div class="users-layout"> <aside>Sidebar</aside> <main> <RouterView /> <!-- Hier werden children gerendert --> </main> </div></template>Navigation Guards
Abschnitt betitelt „Navigation Guards“const router = createRouter({ /* ... */ })
// Vor jeder Navigationrouter.beforeEach((to, from) => { const isAuthenticated = checkAuth()
if (to.meta.requiresAuth && !isAuthenticated) { return { name: 'login' } // Umleiten }
// undefined oder true = Navigation erlaubt})
// Nach jeder Navigationrouter.afterEach((to, from) => { document.title = to.meta.title || 'My App'})Per-Route
Abschnitt betitelt „Per-Route“const routes = [ { path: '/admin', component: AdminView, beforeEnter: (to, from) => { if (!isAdmin()) { return { name: 'home' } } } }, { path: '/dashboard', component: DashboardView, // Mehrere Guards beforeEnter: [checkAuth, checkPermission, logAccess] }]In-Component
Abschnitt betitelt „In-Component“<script setup>import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'import { ref } from 'vue'
const hasUnsavedChanges = ref(false)
// Vor Verlassen der RouteonBeforeRouteLeave((to, from) => { if (hasUnsavedChanges.value) { const answer = confirm('Änderungen verwerfen?') if (!answer) return false // Navigation abbrechen }})
// Bei Param-Änderung (gleiche Komponente)onBeforeRouteUpdate((to, from) => { // z.B. /users/1 → /users/2 fetchUser(to.params.id)})</script>Route Meta Fields
Abschnitt betitelt „Route Meta Fields“const routes = [ { path: '/admin', component: AdminView, meta: { requiresAuth: true, roles: ['admin'], title: 'Admin Dashboard' } }, { path: '/public', component: PublicView, meta: { requiresAuth: false } }]router.beforeEach((to) => { // Meta von verschachtelten Routen zusammenführen if (to.matched.some(record => record.meta.requiresAuth)) { if (!isLoggedIn()) return { name: 'login' } }})Lazy Loading (Code Splitting)
Abschnitt betitelt „Lazy Loading (Code Splitting)“const routes = [ { path: '/', component: HomeView // Sofort geladen }, { path: '/about', // Dynamischer Import → separater Chunk component: () => import('@/views/AboutView.vue') }, { path: '/admin', // Mit Chunk-Name für besseres Debugging component: () => import(/* webpackChunkName: "admin" */ '@/views/AdminView.vue') }]History Modes
Abschnitt betitelt „History Modes“import { createWebHistory } from 'vue-router'
createRouter({ history: createWebHistory(), routes})- URL:
example.com/users - Server-Konfiguration nötig
- SEO-freundlich
import { createWebHashHistory } from 'vue-router'
createRouter({ history: createWebHashHistory(), routes})- URL:
example.com/#/users - Keine Server-Konfiguration
- Für statisches Hosting
Scroll Behavior
Abschnitt betitelt „Scroll Behavior“const router = createRouter({ history: createWebHistory(), routes, scrollBehavior(to, from, savedPosition) { // Bei Browser-Back: gespeicherte Position if (savedPosition) { return savedPosition }
// Bei Hash-Link: zu Element scrollen if (to.hash) { return { el: to.hash, behavior: 'smooth' } }
// Standard: nach oben return { top: 0 } }})Dokumentation
Abschnitt betitelt „Dokumentation“Offizielle Dokumentation:
- Getting Started - Einführung
- Dynamic Routing
- Navigation Guards
- Lazy Loading
API Referenz: