Appearance
Kapitel 30: Vue Router (Teil 4) - Verschachtelte Routen
📙 Lernziel: Verschachtelte Routen (Nested Routes) meistern!
30.1 Was sind verschachtelte Routen?
Verschachtelte Routen ermöglichen Hierarchien in der Navigation.
Beispiel-Szenario:
/ → Layout.vue (mit <router-view>)
├── /user → UserList.vue
├── /user/:id → UserDetail.vue
│ ├── /user/:id/profile → UserProfile.vue
│ └── /user/:id/posts → UserPosts.vue
└── /about → About.vueVorteile:
- ✅ Komplexe Layouts
- ✅ Wiederverwendbare Eltern-Komponenten
- ✅ Bessere Organisation
30.2 Verschachtelte Routen konfigurieren
Schritt 1: Router-Konfiguration (router/index.js)
javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Layout from '../views/Layout.vue'
import Home from '../views/Home.vue'
import UserList from '../views/UserList.vue'
import UserDetail from '../views/UserDetail.vue'
import UserProfile from '../views/UserProfile.vue'
import UserPosts from '../views/UserPosts.vue'
const routes = [
{
path: '/',
component: Layout,
children: [
{ path: '', component: Home },
{ path: 'user', component: UserList },
{
path: 'user/:id',
component: UserDetail,
children: [
{ path: 'profile', component: UserProfile },
{ path: 'posts', component: UserPosts }
]
}
]
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default routerWichtig:
- ✅
childrenArray für verschachtelte Routen - ✅ Eltern-Route braucht
<router-view>in Template
30.3 Eltern-Komponente mit <router-view>
Layout.vue (Eltern-Komponente):
vue
<!-- views/Layout.vue -->
<script setup>
// Keine Importe nötig
</script>
<template>
<div class="layout">
<header>
<nav>
<router-link to="/">Start</router-link> |
<router-link to="/user">Benutzer</router-link>
</nav>
</header>
<main>
<!-- Hier werden Kinder-Routen gerendert -->
<router-view />
</main>
<footer>
<p>© 2026 Meine App</p>
</footer>
</div>
</template>
<style scoped>
.layout {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
background: #42b883;
padding: 15px;
margin-bottom: 20px;
}
nav a {
color: white;
text-decoration: none;
margin: 0 10px;
}
main {
min-height: 400px;
}
footer {
background: #35495e;
color: white;
padding: 10px;
text-align: center;
margin-top: 20px;
}
</style>30.4 Kind-Routen erstellen
UserList.vue (Kind-Route):
vue
<!-- views/UserList.vue -->
<script setup>
import { ref } from 'vue'
const users = ref([
{ id: 1, name: 'Max' },
{ id: 2, name: 'Anna' },
{ id: 3, name: 'Tom' }
])
</script>
<template>
<div class="user-list">
<h2>Benutzerliste</h2>
<ul>
<li v-for="user in users" :key="user.id">
<router-link :to="`/user/${user.id}`">
{{ user.name }}
</router-link>
</li>
</ul>
</div>
</template>
<style scoped>
.user-list ul {
list-style: none;
padding: 0;
}
.user-list li {
padding: 10px;
border-bottom: 1px solid #ddd;
}
.user-list a {
text-decoration: none;
color: #42b883;
}
</style>UserDetail.vue (Eltern für weitere Kinder):
vue
<!-- views/UserDetail.vue -->
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const userId = route.params.id
</script>
<template>
<div class="user-detail">
<h2>Benutzer {{ userId }}</h2>
<nav>
<router-link :to="`/user/${userId}/profile`">Profil</router-link> |
<router-link :to="`/user/${userId}/posts`">Beiträge</router-link>
</nav>
<!-- Hier werden UserProfile.vue oder UserPosts.vue gerendert -->
<router-view />
</div>
</template>
<style scoped>
.user-detail nav {
margin: 20px 0;
}
.user-detail nav a {
margin: 0 10px;
text-decoration: none;
color: #42b883;
}
</style>UserProfile.vue (Enkel-Route):
vue
<!-- views/UserProfile.vue -->
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>
<template>
<div class="user-profile">
<h3>Profil</h3>
<p>Benutzer-ID: {{ route.params.id }}</p>
<p>Name: Max Mustermann</p>
<p>Email: max@example.com</p>
</div>
</template>UserPosts.vue (Enkel-Route):
vue
<!-- views/UserPosts.vue -->
<script setup>
import { ref } from 'vue'
const posts = ref([
{ id: 1, title: 'Vue 3 lernen' },
{ id: 2, title: 'Composition API verstehen' }
])
</script>
<template>
<div class="user-posts">
<h3>Beiträge</h3>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
</div>
</template>30.5 Standard-Route (Default Route)
Kind-Route als Standard anzeigen:
javascript
// router/index.js
const routes = [
{
path: '/user/:id',
component: UserDetail,
children: [
{ path: '', component: UserProfile }, // Standard
{ path: 'profile', component: UserProfile },
{ path: 'posts', component: UserPosts }
]
}
]Ergebnis:
/user/123→ ZeigtUserDetail.vue+UserProfile.vue/user/123/profile→ ZeigtUserDetail.vue+UserProfile.vue/user/123/posts→ ZeigtUserDetail.vue+UserPosts.vue
30.6 Übung: Dashboard mit verschachtelten Routen
Aufgabe: Erstelle ein Dashboard mit Sidebar-Navigation.
Lösung:
1. Router konfigurieren (router/index.js):
javascript
import { createRouter, createWebHistory } from 'vue-router'
import DashboardLayout from '../views/DashboardLayout.vue'
import DashboardHome from '../views/DashboardHome.vue'
import DashboardSettings from '../views/DashboardSettings.vue'
import DashboardAnalytics from '../views/DashboardAnalytics.vue'
const routes = [
{
path: '/dashboard',
component: DashboardLayout,
children: [
{ path: '', component: DashboardHome },
{ path: 'settings', component: DashboardSettings },
{ path: 'analytics', component: DashboardAnalytics }
]
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router2. DashboardLayout.vue erstellen:
vue
<!-- views/DashboardLayout.vue -->
<script setup>
// Keine Importe nötig
</script>
<template>
<div class="dashboard-layout">
<aside class="sidebar">
<h3>Dashboard</h3>
<nav>
<router-link to="/dashboard">Home</router-link>
<router-link to="/dashboard/settings">Einstellungen</router-link>
<router-link to="/dashboard/analytics">Analytik</router-link>
</nav>
</aside>
<main class="content">
<router-view />
</main>
</div>
</template>
<style scoped>
.dashboard-layout {
display: flex;
min-height: 100vh;
}
.sidebar {
width: 250px;
background: #35495e;
color: white;
padding: 20px;
}
.sidebar h3 {
margin-top: 0;
}
.sidebar nav a {
display: block;
color: white;
text-decoration: none;
padding: 10px;
margin: 5px 0;
border-radius: 4px;
}
.sidebar nav a:hover {
background: rgba(255, 255, 255, 0.1);
}
.content {
flex: 1;
padding: 20px;
}
</style>3. Kind-Komponenten erstellen:
vue
<!-- views/DashboardHome.vue -->
<template>
<div>
<h2>Dashboard Home</h2>
<p>Willkommen im Dashboard!</p>
</div>
</template>vue
<!-- views/DashboardSettings.vue -->
<template>
<div>
<h2>Einstellungen</h2>
<p>Hier kannst du Einstellungen vornehmen.</p>
</div>
</template>vue
<!-- views/DashboardAnalytics.vue -->
<template>
<div>
<h2>Analytik</h2>
<p>Hier sind deine Analysedaten.</p>
</div>
</template>✅ Zusammenfassung
In diesem Kapitel hast du gelernt:
- ✅ Was verschachtelte Routen sind
- ✅ Verschachtelte Routen konfigurieren (
children) - ✅ Eltern-Komponente mit
<router-view> - ✅ Kind-Routen erstellen
- ✅ Standard-Route (Default Route)
- ✅ Praxis: Dashboard mit verschachtelten Routen
🎯 Nächster Schritt: In Kapitel 31 lernst du Weiterleitungen (Redirects) und 404-Seiten!
← Zurück zu Kapitel 29: Route-ParameterWeiter zu Kapitel 31: Redirects & 404 →
