Nested Routes

Sedanur İnan
3 min read1 hour ago

--

Örneğin ürünleri listeleyecek bir sayfa hazırlıyoruz ve bu ürün listesi sayfamızda da üç alt kategori daha var. Ürün detayları, kayıt ve düzenleme. Bir ürün listesi ve alt kategorilerininin routerını ayarlarken farklı çözümler uygulayabiliriz. İlk akla gelen her biri için ayrı bir route objesi oluşturmak olur.

import { createRouter, createWebHistory } from 'vue-router'
import About from '@/views/About.vue'
import EventList from '@/views/EventList.vue'
import EventDetails from '@/views/event/Details.vue'
import EventRegister from '@/views/event/Register.vue'
import EventEdit from '@/views/event/Edit.vue'

const routes = [
{
path: '/',
name: 'EventList',
component: EventList
props: route => ({ page: parseInt(route.query.page) || 1 })
},
{
path: '/event/:id',
name: 'EventDetails',
props: true,
component: EventDetails
},
{
path: '/event/:id/register',
name: 'EventRegister',
props: true,
component: EventRegister
},
{
path: '/event/:id/edit',
name: 'EventEdit',
props: true,
component: EventEdit
},
...

Bu çözüm doğru fakat bir çok duplicate kod içermektedir. Oluşturduğumuz her sayfada router-link’i bu şekilde kullanmamıza sebep olur:

<script setup>
import { onMounted, ref } from 'vue'
import EventService from '@/services/EventService.js'

const { id } = defineProps(['id'])

const event = ref(null)
onMounted(() => {
EventService.getEvent(id)
.then(response => {
event.value = response.data
})
.catch(error => {
console.log(error)
})
})
</script>
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails', params: { id } }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister', params: { id } }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit', params: { id } }"
>Edit</router-link
>
</div>
<p>Edit the event here</p>
</div>
</template>

Takdir edersiniz ki register,edit, detail bu üç sayfa için de tekrar aynı yapıyı kopyalamak çok da iyi bir çözüm değil. Çünkü her sayfada tekrar tekrar networke istek atıyoruz.

Buradaki duplicate yapıyı çözmek ve daha iyi bir kod yazmak için şu şekilde bir yol izleyebiliriz.

1- Ana bir component oluştur ve bu componentin içinde tekrar eden yapıyı çağır.

2- Bu ana componentte router-view kullan ve event ile ilgili bilgileri prop kullanarak yönet. Bu component bizim parent componentimiz ve burada networke istek atıp zaten event bilgilerini alıyoruz. Childda sadece defineProps([‘event’]) olarak çağırmamız yetecek.

<script setup>
import { onMounted, ref } from 'vue'
import EventService from '@/services/EventService.js'

const { id } = defineProps(['id'])

const event = ref(null)
onMounted(() => {
EventService.getEvent(id)
.then(response => {
event.value = response.data
})
.catch(error => {
console.log(error)
})
})
</script>
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails', params: { id } }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister', params: { id } }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit', params: { id } }"
>Edit</router-link
>
</div>
<router-view :event="event" />
</div>
</template>

3- Router içindeki index dosyanı düzenle. Burada Layout componentini import ettik ve detail,register,edit componentlerini onun children’ı olarak tanımladık.

import { createRouter, createWebHistory } from 'vue-router'
import EventList from '../views/EventList.vue'
import EventLayout from '../views/event/Layout.vue'
import EventDetails from '../views/event/Details.vue'
import EventRegister from '../views/event/Register.vue'
import EventEdit from '../views/event/Edit.vue'
import About from '../views/About.vue'

const routes = [
{
path: '/',
name: 'EventList',
component: EventList,
props: route => ({ page: parseInt(route.query.page) || 1 })
},
{
path: '/event/:id',
name: 'EventLayout',
props: true,
component: EventLayout,
children: [ // <-----
{
path: '',
name: 'EventDetails',
component: EventDetails
},
{
path: 'register',
name: 'EventRegister',
component: EventRegister
},
{
path: 'edit',
name: 'EventEdit',
component: EventEdit
}
]
},
...

4 — Son olarak layout componentimizde yer alan params ifadesini siliyoruz. Çünkü zaten id bilgisi parentta çıkıyor ve kullandığımız yapı sayesinde tüm childrenlara aktarılıyor.

    <div id="nav">
<router-link :to="{ name: 'EventDetails }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister' }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit' }"
>Edit</router-link
>
</div>

Bu şekilde componentlerimizde tekrar eden network isteklerini ve yapıları optimize edebilir ve daha sağlıklı bir kod yazabiliriz.

Bu yazıda geçen tüm bilgiler “vuemastery” sitesindeki derslerimden çıkardığım notlardır.

--

--