Vue.js’te İç İçe (Nested) Rotalar Nasıl Kullanılır? Kapsamlı Bir Rehber
Tek sayfalık uygulamaların (Single Page Applications – SPA) geliştirilmesinde, kullanıcı arayüzünün farklı bölümlerine dinamik olarak erişim sağlamak ve yönetmek kritik bir öneme sahiptir. Vue.js ekosisteminde bu görevi üstlenen ana araç Vue Router’dır. Vue Router, uygulamanızın farklı URL’ler arasında geçiş yapmasını sağlarken, aynı zamanda karmaşık UI yapılarını düzenlemenize olanak tanır. Bu düzenleme yeteneklerinin en güçlülerinden biri de “iç içe (nested) rotalar” konseptidir.
İç içe rotalar, bir ana (parent) rotanın altında birden fazla alt (child) rotanın tanımlanmasıyla oluşan hiyerarşik bir yapı sunar. Bu yapı, özellikle bir ana bileşenin kendi içinde farklı alt görünümleri barındırması gereken senaryolarda devreye girer. Örneğin, bir kullanıcı profil sayfası düşünün: bu sayfa “Profil Bilgileri”, “Gönderiler” ve “Ayarlar” gibi farklı sekmelere sahip olabilir. Bu sekmelerin her biri, ana profil sayfasının bir alt rotası olarak tanımlanabilir ve ana profil sayfasının düzenini (header, sidebar vb.) korurken sadece içerik alanını değiştirebilir. Bu yaklaşım, kodun daha düzenli olmasını, bileşenlerin yeniden kullanılabilirliğini artırmasını ve uygulamanın genel mimarisini daha anlaşılır kılmasını sağlar.
Bu makalede, Vue.js’te iç içe rotaların ne olduğunu, neden kullanıldığını, nasıl yapılandırıldığını ve gerçek dünya senaryolarında nasıl uygulandığını adım adım ele alacağız. Ayrıca, bu güçlü özelliği kullanırken karşılaşabileceğiniz yaygın durumları, en iyi uygulamaları ve ipuçlarını da inceleyeceğiz.
İç İçe Rotalar Nedir ve Neden Kullanılır?
İç içe rotalar, adından da anlaşılacağı gibi, bir rotanın başka bir rotayı içermesi durumudur. Vue Router’da bu, bir ana rotanın children özelliğini kullanarak tanımlanır. Bu özellik, ana rotanın altında, kendi URL yollarına ve bileşenlerine sahip alt rotaların bir dizisini barındırır.
Örnek Bir Senaryo:
Bir e-ticaret uygulamasında “Ürünler” bölümü olduğunu varsayalım. Bu bölümün altında “Tüm Ürünler”, “Kategoriye Göre Ürünler” ve “Ürün Detayı” gibi alt bölümler olabilir.
– /products (Ana rota, tüm ürünleri listeleyen bir düzeni gösterir)
– /products/all (Tüm ürünlerin listesi)
– /products/category/:categoryId (Belirli bir kategoriye ait ürünler)
– /products/:productId (Belirli bir ürünün detay sayfası)
Bu yapıda, /products rotası bir ana bileşeni (örneğin ProductsLayout.vue) yükler. Bu ana bileşen, kendi içinde bir etiketine sahip olacaktır. /products/all gibi alt rotalara gidildiğinde, bu alt rotaların bileşenleri (örneğin AllProducts.vue) ana bileşenin etiketi içine render edilir. Böylece, ana bileşenin etrafındaki menü, başlık veya filtreleme alanı gibi ortak UI öğeleri korunurken sadece iç kısım değişir.
İç İçe Rotaları Kullanmanın Avantajları:
1. UI Organizasyonu ve Hiyerarşisi: Uygulamanızın kullanıcı arayüzünü mantıksal bir hiyerarşi içinde düzenlemenizi sağlar. Bu, karmaşık arayüzlerin daha yönetilebilir olmasını sağlar.
2. Paylaşılan Düzenler (Shared Layouts): Bir ana bileşen, alt rotalar arasında paylaşılacak bir düzen (layout) sağlayabilir. Bu, başlık çubuğu, kenar çubuğu, alt bilgi gibi ortak UI öğelerinin her alt rota için tekrar tekrar tanımlanmasını önler.
3. Bileşen Yeniden Kullanılabilirliği: Ortak bir düzeni paylaşan alt rotalar, daha modüler ve yeniden kullanılabilir bileşenler oluşturmayı teşvik eder.
4. Veri Geçişi ve Parametre Yönetimi: Ana rotadan alt rotalara parametrelerin geçişi daha doğal bir şekilde gerçekleşebilir. Örneğin, bir userId parametresi ana rotada tanımlanıp, tüm alt rotalar tarafından kullanılabilir.
5. Kod Bakımı ve Okunabilirlik: Rota tanımlarını ve bileşen yapılarını daha düzenli hale getirerek kodun okunabilirliğini ve bakımını kolaylaştırır.
6. Geliştirici Deneyimi: Geliştiricilerin, uygulamanın farklı bölümlerinin nasıl ilişkili olduğunu ve hangi bileşenlerin hangi bağlamda render edildiğini daha kolay anlamalarına yardımcı olur.
Vue Router Kurulumu ve Temel Yapılandırma
İç içe rotaları kullanmaya başlamadan önce, Vue Router’ın projenizde kurulu ve temel olarak yapılandırılmış olması gerekir.
1. Vue Router Kurulumu:
Projenize Vue Router’ı npm veya yarn ile yükleyin:
npm install vue-router@4
veya
yarn add vue-router@4
Bu komut Vue 3 ile uyumlu Vue Router v4’ü yükleyecektir.
2. Router Dosyasını Oluşturma:
Genellikle src/router/index.js yolunda bir router yapılandırma dosyası oluşturulur.
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import HomeView from '../views/HomeView.vue'; // Örnek ana sayfa bileşeni
const routes = [
{
path: '/',
name: 'home',
component: HomeView
}
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
export default router;
3. Vue Uygulamasına Entegre Etme:
src/main.js dosyasında router’ı Vue uygulamanıza ekleyin:
// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // Oluşturduğumuz router'ı import et
createApp(App).use(router).mount('#app');
4. App.vue‘de :
Uygulamanızın ana bileşeni olan App.vue içinde, rotaların bileşenlerinin render edileceği yeri belirtmek için etiketini kullanın:
Bu temel kurulum tamamlandıktan sonra, iç içe rotaları tanımlamaya başlayabiliriz.
İç İçe Rotaları Adım Adım Uygulama
Şimdi, bir kullanıcı profili örneği üzerinden iç içe rotaların nasıl yapılandırıldığını detaylı bir şekilde inceleyelim.
Senaryo:
Bir kullanıcı profili sayfası (/users/:id) aşağıdaki alt sekmelere sahip olacak:
– /users/:id (Varsayılan olarak kullanıcı profil bilgilerini gösterir)
– /users/:id/posts (Kullanıcının gönderilerini gösterir)
– /users/:id/settings (Kullanıcı ayarlarını gösterir)
1. Bileşenleri Oluşturma:
Öncelikle gerekli bileşenleri oluşturalım.
a. Ana Bileşen (Parent Component): UserLayout.vue
Bu bileşen, kullanıcı profilinin genel düzenini sağlayacak ve alt rotaların render edileceği ‘i içerecektir. Ayrıca, alt rotalar arasında gezinmek için ‘leri de barındıracaktır.
Kullanıcı Profili: {{ $route.params.id }}
b. Alt Bileşenler (Child Components):
Profil Bilgileri
Kullanıcı ID: {{ $route.params.id }}
Bu alanda kullanıcının genel profil bilgileri görüntülenecektir.
Kullanıcı Gönderileri
Kullanıcı ID: {{ $route.params.id }}
Bu alanda kullanıcının yaptığı gönderiler listelenecektir.
Kullanıcı Ayarları
Kullanıcı ID: {{ $route.params.id }}
Bu alanda kullanıcının hesap ayarları yönetilecektir.
2. Rotaları Yapılandırma (router/index.js):
Şimdi router/index.js dosyasını güncelleyerek iç içe rotaları tanımlayalım. Ana rotayı UserLayout bileşenine bağlayacak ve children özelliği ile alt rotaları belirleyeceğiz.
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import HomeView from '../views/HomeView.vue';
import UserLayout from '../views/UserLayout.vue'; // Ana bileşeni import et
import UserProfile from '../views/UserProfile.vue'; // Alt bileşenleri import et
import UserPosts from '../views/UserPosts.vue';
import UserSettings from '../views/UserSettings.vue';
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/users/:id', // Ana rotanın yolu
name: 'user-layout', // Ana rotaya bir isim verilebilir
component: UserLayout, // Ana rotanın bileşeni
children: [ // Alt rotalar burada tanımlanır
{
path: '', // Boş yol, ana rotaya doğrudan erişildiğinde varsayılan olarak yüklenecek alt rota
name: 'user-profile',
component: UserProfile
},
{
path: 'posts', // '/users/:id/posts' yolunu oluşturur (ana yola göreceli)
name: 'user-posts',
component: UserPosts
},
{
path: 'settings', // '/users/:id/settings' yolunu oluşturur
name: 'user-settings',
component: UserSettings
}
]
}
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
export default router;
Açıklamalar:
– path: '/users/:id' ana rotayı tanımlar. :id bir rota parametresidir ve UserLayout bileşeni ile alt bileşenlerde $route.params.id ile erişilebilir.
– children dizisi, bu ana rotanın altındaki tüm rotaları içerir.
– Bir alt rotanın path‘i boş bir dize '' olduğunda, bu alt rota ana rotanın yoluyla eşleştiğinde (örn. /users/123) varsayılan olarak render edilecektir. Bu, ana rotaya gidildiğinde otomatik olarak bir alt görünümün yüklenmesini sağlar.
– Alt rotaların path‘leri, ana rotanın path‘ine görecelidir. Yani path: 'posts' aslında /users/:id/posts anlamına gelir. Başına / koymadığınız sürece göreceli olarak kabul edilir.
– name özelliği, rotalara isim vererek programatik gezinmeyi ve kullanımını kolaylaştırır. router-link :to="{ name: 'user-posts', params: { id: $route.params.id } }" şeklinde kullanmak, URL’i doğrudan yazmaktan daha sağlamdır.
3. App.vue‘de Ana Rota Linki:
App.vue‘ye örnek bir kullanıcı profili linki ekleyerek test edebiliriz:
Artık /users/123 adresine gittiğinizde UserLayout bileşeni yüklenecek, içinde UserProfile bileşeni görünecek ve navigasyon linklerini kullanarak “Gönderiler” veya “Ayarlar” sekmelerine geçiş yapabileceksiniz.
Gelişmiş İç İçe Rota Konseptleri
İç içe rotalar sadece temel hiyerarşik yapılar için değil, daha karmaşık senaryolar için de güçlü özellikler sunar.
1. İç İçe Named Views (Adlandırılmış Görünümler)
Bazen bir ana bileşen içinde birden fazla örneğine ihtiyacınız olabilir. Örneğin, bir dashboard layout’unda hem bir kenar çubuğu (sidebar) hem de ana içerik alanı olabilir. Bu durumda, adlandırılmış görünümler devreye girer.
Dashboard Başlığı
Rota yapılandırmasında, components özelliğini kullanarak her bir ‘e hangi bileşenin atanacağını belirtiriz:
// router/index.js
import DashboardLayout from '../views/DashboardLayout.vue';
import DashboardMain from '../views/DashboardMain.vue';
import DashboardSidebar from '../views/DashboardSidebar.vue';
const routes = [
{
path: '/dashboard',
component: DashboardLayout,
children: [
{
path: '', // Varsayılan dashboard görünümü
components: {
default: DashboardMain, // Adlandırılmamış router-view için
sidebar: DashboardSidebar // 'sidebar' adlı router-view için
}
}
]
}
];
Bu şekilde, /dashboard rotasına gidildiğinde DashboardLayout yüklenir, DashboardMain ana ‘e, DashboardSidebar ise ‘a render edilir.
2. Rota Parametrelerini Props Olarak Geçirme
Bileşenlerinizde $route.params üzerinden rota parametrelerine doğrudan erişmek yerine, bunları bileşen props’ları olarak geçirmek daha temiz ve test edilebilir bir yaklaşımdır.
// router/index.js
const routes = [
{
path: '/users/:id',
component: UserLayout,
props: true, // Ana bileşene tüm parametreleri prop olarak geçirir
children: [
{
path: '',
name: 'user-profile',
component: UserProfile,
props: true // Alt bileşene tüm parametreleri prop olarak geçirir
},
// ... diğer alt rotalar
]
}
];
Şimdi UserLayout.vue ve UserProfile.vue bileşenlerinde id parametresini bir prop olarak tanımlayabiliriz:
Kullanıcı Profili: {{ id }}
props: true yerine daha spesifik kontrol için bir fonksiyon da kullanabilirsiniz:
{
path: '/users/:id',
component: UserLayout,
props: (route) => ({ userId: route.params.id }), // 'id' parametresini 'userId' prop'u olarak geçir
// ...
}
3. Programatik Gezinme (Programmatic Navigation)
kullanmak yerine JavaScript koduyla da rotalar arasında geçiş yapabilirsiniz. Bu, genellikle form gönderimleri, buton tıklamaları veya bir API çağrısının başarılı olması gibi durumlarda kullanılır.
// Bir bileşenin script kısmında
export default {
methods: {
goToUserSettings() {
// Named route ile
this.$router.push({ name: 'user-settings', params: { id: this.userId } });
// Path ile (göreceli olarak da kullanılabilir)
// this.$router.push(/users/${this.userId}/settings);
},
goBack() {
this.$router.go(-1); // Bir önceki sayfaya dön
}
}
}
İç içe rotalarda programatik gezinme yaparken, alt rotanın tam yolunu veya adını ve gerekli tüm parametreleri doğru bir şekilde sağlamak önemlidir.
4. Meta Alanları (Meta Fields)
Rotalara özel veriler eklemek için meta özelliğini kullanabilirsiniz. Bu, genellikle yetkilendirme (authorization) veya sayfa başlığı gibi bilgiler için faydalıdır.
// router/index.js
const routes = [
{
path: '/admin',
component: AdminLayout,
meta: { requiresAuth: true, role: 'admin' }, // Ana rota için meta
children: [
{
path: 'dashboard',
component: AdminDashboard,
meta: { title: 'Yönetim Paneli' } // Alt rota için meta
}
]
}
];
Bu meta alanlarına navigasyon koruyucuları (navigation guards) içinde erişebilir ve belirli rotalara erişimi kontrol edebilirsiniz.
5. Navigasyon Koruyucuları (Navigation Guards)
Navigasyon koruyucuları, bir rotaya erişimi engellemek veya yönlendirmek için kullanılır. beforeEach (global), beforeEnter (rota bazlı) ve beforeRouteEnter/Update/Leave (bileşen bazlı) gibi farklı türleri vardır.
İç içe rotalarda, bir ana rotanın beforeEnter koruyucusu, o rotaya ve tüm alt rotalarına uygulanır. Alt rotaların kendi beforeEnter koruyucuları da olabilir.
// router/index.js
const routes = [
{
path: '/admin',
component: AdminLayout,
meta: { requiresAuth: true },
beforeEnter: (to, from, next) => {
// Bu koruyucu, '/admin' ve tüm alt rotalarına uygulanır
if (localStorage.getItem('token')) {
next(); // Devam et
} else {
next('/login'); // Giriş sayfasına yönlendir
}
},
children: [
{
path: 'dashboard',
component: AdminDashboard,
beforeEnter: (to, from, next) => {
// Bu koruyucu sadece '/admin/dashboard' rotasına uygulanır
console.log('Admin Dashboard rotasına giriliyor...');
next();
}
}
]
}
];
Global beforeEach koruyucusu, her navigasyonda çalışır ve tüm rotaların meta alanlarını kontrol etmek için idealdir:
// router/index.js (en altta, router oluşturulduktan sonra)
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !localStorage.getItem('token')) {
next('/login');
} else {
next();
}
});
6. Lazy Loading (Tembel Yükleme / Kod Bölme)
Uygulamanız büyüdükçe, tüm bileşenleri başlangıçta yüklemek performans sorunlarına yol açabilir. Lazy loading, bileşenleri yalnızca ihtiyaç duyulduğunda yükleyerek bu sorunu çözer. Bu, iç içe rotalar için de geçerlidir ve özellikle büyük uygulamalarda önemlidir.
// router/index.js
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/HomeView.vue') // Lazy load
},
{
path: '/users/:id',
component: () => import('../views/UserLayout.vue'), // Ana bileşeni lazy load et
children: [
{
path: '',
name: 'user-profile',
component: () => import('../views/UserProfile.vue') // Alt bileşeni lazy load et
},
{
path: 'posts',
name: 'user-posts',
component: () => import('../views/UserPosts.vue')
},
{
path: 'settings',
name: 'user-settings',
component: () => import('../views/UserSettings.vue')
}
]
}
];
component: () => import(...) syntax’ı, bileşenleri ayrı JavaScript parçacıklarına böler ve yalnızca ilgili rota ziyaret edildiğinde yüklenmelerini sağlar. Bu, ilk yükleme süresini önemli ölçüde azaltabilir.
7. 404 Sayfaları ve Catch-all Rotalar
Tanımlanmamış bir yola gidildiğinde kullanıcıyı bir 404 hata sayfasına yönlendirmek iyi bir kullanıcı deneyimi sağlar. Bunu, tüm rotaların en altına bir “catch-all” (her şeyi yakalayan) rota ekleyerek yapabilirsiniz:
// router/index.js
import NotFound from '../views/NotFound.vue'; // 404 sayfa bileşeni
const routes = [
// ... diğer rotalarınız
{
path: '/:pathMatch(.)', // Her şeyi yakalar
name: 'NotFound',
component: NotFound
}
];
Bu rota, diğer hiçbir rotayla eşleşmeyen tüm URL’leri yakalayacaktır.
Gerçek Dünya Senaryoları ve İpuçları
İç içe rotalar, Vue.js uygulamalarında birçok yaygın senaryoda kullanılır:
* Yönetim Panelleri (Admin Dashboards): Kenar çubuğu ve üst menü gibi sabit bir düzenin içinde farklı yönetim sayfaları (kullanıcı yönetimi, ürün yönetimi, istatistikler).
* Profil Sayfaları: Kullanıcı profili, ayarlar, bildirimler, gönderiler gibi sekmeli görünümler.
* E-ticaret Ürün Sayfaları: Ürün listesi, kategoriye göre filtreleme, ürün detayları, yorumlar.
* Ayarlar Bölümleri: Hesap ayarları, gizlilik ayarları, bildirim ayarları gibi alt kategoriler.
İpuçları ve Yaygın Hatalar:
* ‘i Unutmayın: Ana bileşeninizde etiketini eklemeyi unutmayın, aksi takdirde alt bileşenleriniz render edilmez.
* Göreceli Yollar: Alt rotaların yollarını tanımlarken (path: 'posts'), ana rotaya göreceli olduklarını unutmayın. Mutlak yol (path: '/posts') kullanırsanız, bu rota ana rotanın dışında, kök dizinde aranır.
* Parametre Yönetimi: Rota parametrelerini (:id) doğru bir şekilde tanımladığınızdan ve UserLayout gibi ana bileşenlerdeki ‘lerde de bu parametreleri kullandığınızdan emin olun.
* Adlandırılmış Rotalar: name özelliğini kullanarak rotalara isim vermek, URL yapınız değişse bile router-link‘lerinizin ve programatik gezinmenizin çalışmaya devam etmesini sağlar.
* Lazy Loading’i Akıllıca Kullanın: Tüm rotaları lazy load etmek her zaman en iyi çözüm değildir. Uygulamanızın başlangıçta ihtiyaç duyduğu kritik bileşenleri önceden yüklemeyi düşünebilirsiniz.
* Hata Ayıklama: Rotalarınızla ilgili bir sorun yaşıyorsanız, tarayıcının geliştirici araçlarındaki Vue devtools eklentisini kullanarak mevcut rota durumunu ve bileşen hiyerarşisini inceleyin. console.log(this.$route) ile rota nesnesini kontrol etmek de faydalıdır.
Sonuç
Vue.js’te iç içe rotalar, modern ve karmaşık tek sayfalık uygulamalar geliştirirken vazgeçilmez bir araçtır. Uygulamanızın kullanıcı arayüzünü mantıksal ve hiyerarşik bir şekilde düzenlemenize, paylaşılan düzenleri etkili bir şekilde kullanmanıza ve bileşenlerin yeniden kullanılabilirliğini artırmanıza olanak tanır. Bu sayede, uygulamanızın kod tabanı daha temiz, daha bakımı kolay ve daha ölçeklenebilir hale gelir.
Bu makalede ele aldığımız temel kurulumdan gelişmiş konseptlere (named views, props, lazy loading, navigation guards) kadar tüm adımlar, Vue Router’ın gücünü tam olarak kullanmanıza yardımcı olacaktır. İç içe rotaları doğru bir şekilde anlayıp uygulayarak, kullanıcılarınıza daha sezgisel ve tutarlı bir deneyim sunan, aynı zamanda geliştirici dostu ve performanslı Vue.js uygulamaları inşa edebilirsiniz. Unutmayın, iyi bir rota mimarisi, uygulamanızın uzun vadeli başarısının temelini oluşturur.