Vue Router, Vue 3 uygulamalarında tek sayfa (SPA) yönlendirmenin resmi çözümüdür: sayfa yenilenmeden URL'i değiştirir, doğru bileşeni ekrana getirir ve tarayıcının geri/ileri düğmeleriyle uyumlu çalışır. Bu rehberde rota tanımını, dinamik parametreleri, programatik navigasyonu ve erişim kontrolünü sağlayan navigation guard'ları gerçek örneklerle ele alıyoruz. Anlatım Vue Router 4 (Vue 3 ile kullanılan sürüm) içindir.
Kurulum ve temel rota tanımı
Paketi kurun ve bir router örneği oluşturun. createRouter bir history modu ve bir routes dizisi alır:
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,
})
Ardından router'ı uygulamaya bağlayın:
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { router } from './router'
createApp(App).use(router).mount('#app')
Bileşenin nereye çizileceğini <router-view> belirler; bağlantıları ise <router-link> ile verirsiniz; böylece tam sayfa yenilemesi olmaz:
<router-link to="/">Ana Sayfa</router-link>
<router-link :to="{ name: 'about' }">Hakkımızda</router-link>
<router-view />
Rotalara isim vermek iyi bir alışkanlıktır: URL yapısı değişse bile name ile yaptığınız bağlantılar bozulmaz.
history modu: web history mi, hash mi?
İki yaygın seçenek vardır. createWebHistory() temiz URL'ler üretir (/about) ama sunucunuzun bilinmeyen tüm yolları index.html'e yönlendirmesini gerektirir; aksi halde sayfa yenilendiğinde 404 alırsınız. createWebHashHistory() ise URL'e bir # ekler (/#/about) ve sunucu yapılandırması gerektirmez — statik barındırmada pratiktir ama estetik açıdan ve SEO için daha zayıftır. Çoğu modern proje web history'yi tercih edip sunucuya bir fallback kuralı ekler.
Dinamik parametreler
Rota yolunda : ile başlayan segmentler dinamik parametredir. Örneğin bir ürün detay sayfası:
const routes = [
{ path: '/users/:id', name: 'user', component: UserDetail },
]
Bileşen içinde parametreye useRoute() ile erişirsiniz. Composition API'de tipik kullanım şöyledir:
<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)
// Aynı bileşen tekrar kullanılırken parametre değişimini izle
watch(() => route.params.id, (id) => load(id))
</script>
Burada kritik bir nokta var: kullanıcı /users/1'den /users/2'ye geçtiğinde Vue aynı bileşen örneğini yeniden kullanır, yani bileşen yeniden oluşturulmaz. Bu yüzden veriyi yeniden çekmek için route.params.id'yi watch ile izlemeniz gerekir. Parametreyi prop olarak almak isterseniz rotada props: true tanımlayın; o zaman bileşeniniz id'yi doğrudan bir prop gibi alır ve test etmesi daha kolay olur.
İsteğe bağlı parametre için :id?, birden çok segmenti yakalamak için ise /:pathMatch(.*)* kalıbını kullanabilirsiniz; ikincisi tipik olarak 404 sayfası için kullanılır.
Programatik navigasyon ve sorgu parametreleri
Bir form gönderildikten veya bir işlem tamamlandıktan sonra koddan yönlendirme yapmak için useRouter() kullanın:
<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>
Sorgu parametreleri (?q=...) route.query üzerinden okunur. Geçmişte yeni bir girdi bırakmadan mevcut adımı değiştirmek için router.replace(), geri gitmek için router.back() kullanılır.
Navigation guard'lar: erişim kontrolü
Guard'lar, bir geçiş gerçekleşmeden önce araya girip onu izin verme, yönlendirme veya iptal etme imkânı verir — kimlik doğrulama için temel araçtır. En sık kullanılan global guard beforeEach'tir:
router.beforeEach((to, from) => {
const isAuth = !!localStorage.getItem('token')
if (to.meta.requiresAuth && !isAuth) {
// Bir konum nesnesi döndürmek geçişi oraya yönlendirir
return { name: 'login', query: { redirect: to.fullPath } }
}
// true veya hiçbir şey döndürmek geçişe izin verir
})
Vue Router 4'te modern stil, next() çağırmak yerine bir değer döndürmektir: false geçişi iptal eder, bir konum nesnesi yeniden yönlendirir, başka her şey (veya undefined) izin verir. Hangi rotaların korunacağını rota tanımındaki meta alanıyla işaretlersiniz:
{
path: '/dashboard',
name: 'dashboard',
component: Dashboard,
meta: { requiresAuth: true },
}
Yalnızca tek bir rotayı korumak isterseniz, o rotaya özel beforeEnter guard'ını kullanabilirsiniz. Bileşen içinde ise onBeforeRouteLeave ile "kaydedilmemiş değişiklikler var, çıkmak istediğinize emin misiniz?" gibi kontroller yapabilirsiniz.
Lazy loading ve iç içe rotalar
Büyük uygulamalarda her görünümü baştan yüklemek ilk açılışı yavaşlatır. Bileşeni dinamik import() ile vererek route bazlı kod bölme (code splitting) elde edersiniz; ilgili parça yalnızca o rotaya gidildiğinde indirilir:
const routes = [
{ path: '/about', component: () => import('../views/About.vue') },
]
İç içe arayüzler (örneğin bir kullanıcı profilinde sekmeler) için children kullanın ve üst bileşenin şablonuna ikinci bir <router-view> koyun:
{
path: '/users/:id',
component: UserLayout,
children: [
{ path: '', component: UserOverview },
{ path: 'posts', component: UserPosts },
],
}
Sık Sorulan Sorular
Parametre değişince sayfam neden güncellenmiyor?
Çünkü Vue Router aynı bileşeni yeniden kullanır ve yeniden oluşturmaz. route.params'ı watch ile izleyip veriyi yeniden çekin ya da bileşene benzersiz bir :key verip yeniden oluşmaya zorlayın.
Sayfayı yenileyince neden 404 alıyorum?
Web history modunda sunucunuz /about gibi yolları bilmez. Sunucuyu, eşleşmeyen tüm istekleri index.html'e yönlendirecek (SPA fallback) şekilde yapılandırın; bunu yapamıyorsanız hash history kullanın.
beforeEach içinde next() mi yoksa return mü kullanmalıyım?
Vue Router 4'te değer döndürmek önerilir; daha temiz ve hata yapmaya daha az açıktır. next() hâlâ desteklenir ama ikisini aynı guard'da karıştırmayın, yoksa geçiş iki kez işlenebilir.
Vue projenizde yönlendirme karmaşıklaştı mı? Rota yapınızı, guard'larınızı ve kod bölmeyi birlikte gözden geçirip sağlam bir mimariye kavuşturalım. Benimle iletişime geçin, ihtiyacınıza uygun bir çözüm kuralım.