Vue Router İleri Düzey Kullanım Senaryoları

# Vue Router İleri Düzey Kullanım Senaryoları Bu rehber, Vue 3 ve Vue Router 4 kullandığınızı varsayar. Composition API (``) ve `createRouter`/`creat...

Vue Router İleri Düzey Kullanım Senaryoları

Vue Router İleri Düzey Kullanım Senaryoları

Bu rehber, Vue 3 ve Vue Router 4 kullandığınızı varsayar. Composition API (<script setup>) ve createRouter/createWebHistory ile temel düzeyde çalışabildiğinizi kabul ediyorum. Amaç; korumalı rotalar, dinamik rota yönetimi, veri ön yükleme, kaydırma davranışı ve yönlendirme güvenliği gibi günlük projelerde tekrar eden ileri senaryoları uygulanabilir biçimde ele almak.

Rota Seviyesinde Yetkilendirme: Meta Alanları ve Global Guard

Sayfaya erişim kontrolünü dağınık if blokları yerine rota tanımındaki meta alanına taşımak, hem okunabilirliği hem de tutarlılığı artırır.

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/panel',
    component: () => import('../views/Dashboard.vue'),
    meta: { requiresAuth: true },
  },
  {
    path: '/giris',
    component: () => import('../views/Login.vue'),
    meta: { guestOnly: true },
  },
]

export const router = createRouter({
  history: createWebHistory(),
  routes,
})

Guard'ı tek bir yerde tanımlayın:

router.beforeEach((to) => {
  const isAuthenticated = !!localStorage.getItem('token')

  if (to.meta.requiresAuth && !isAuthenticated) {
    return { name: 'giris', query: { yonlendir: to.fullPath } }
  }

  if (to.meta.guestOnly && isAuthenticated) {
    return { name: 'panel' }
  }
})

beforeEach içinde return ile döndürülen bir rota nesnesi, navigasyonu iptal edip yeni bir yönlendirme başlatır. next() çağrısına gerek yoktur; Vue Router 4'te guard'lar next olmadan da çalışır ve bu kullanım önerilir.

Beklenen davranış: Oturum açmamış kullanıcı /panel'e gittiğinde /giris?yonlendir=/panel adresine düşer. Giriş sonrası bu query parametresini okuyarak kullanıcıyı kaldığı yere döndürebilirsiniz.

Güvenlik notu: Bu kontrol yalnızca istemci tarafındadır. localStorage içeriği kullanıcı tarafından değiştirilebilir. Gerçek yetkilendirme kararı her zaman sunucuda verilmelidir; istemci guard'ı yalnızca kullanıcı deneyimi katmanıdır.

Dinamik Rota Ekleme ve Çıkarma

Rol tabanlı panellerde rotaların tamamını baştan tanımlamak yerine, oturum açıldıktan sonra eklemek yaygın bir yaklaşımdır.

const adminRoutes = [
  {
    path: '/admin/kullanicilar',
    name: 'admin-kullanicilar',
    component: () => import('../views/admin/Users.vue'),
  },
]

function addAdminRoutes() {
  adminRoutes.forEach((route) => router.addRoute(route))
}

function removeAdminRoutes() {
  if (router.hasRoute('admin-kullanicilar')) {
    router.removeRoute('admin-kullanicilar')
  }
}

Dikkat edilmesi gereken nokta: addRoute ile eklenen bir rota, o an aktif olan URL ile eşleşiyorsa arayüz otomatik güncellenmez. Bu durumda router.replace(router.currentRoute.value.fullPath) çağırarak yeniden eşleştirmeyi tetiklemeniz gerekir. Çıkış (logout) sırasında eklenen rotaları kaldırmayı unutmak, aynı oturumda farklı bir kullanıcının önceki kullanıcının rotalarına erişmesine yol açabilir.

Bileşen İçinde Rota Parametrelerini İzleme

Aynı bileşen farklı parametrelerle yeniden kullanıldığında (örneğin /urun/1 → /urun/2), bileşen yeniden oluşturulmaz. Bu yüzden onMounted içinde parametre okumak yanıltıcıdır.

<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()

watch(
  () => route.params.id,
  async (yeniId) => {
    if (yeniId) {
      await veriyiYukle(yeniId)
    }
  },
  { immediate: true }
)
</script>

immediate: true seçeneği, ilk yüklemede de fonksiyonun çalışmasını sağlar; böylece onMounted içinde ayrıca çağrı yapmanıza gerek kalmaz.

Veri Ön Yükleme: beforeRouteEnter ve beforeResolve

Bir sayfaya girmeden önce veriyi hazırlamak istiyorsanız iki temel yaklaşım vardır.

Bileşen içi guard (yalnızca o bileşene özel):

<script>
export default {
  async beforeRouteEnter(to, from, next) {
    const veri = await api.getir(to.params.id)
    next((vm) => {
      vm.veri = veri
    })
  },
}
</script>

beforeRouteEnter içinde this'e erişemezsiniz çünkü bileşen henüz oluşturulmamıştır. Veriyi next callback'i üzerinden aktarmanız gerekir. Bu kalıp <script setup> ile doğrudan kullanılamaz; Composition API'de onBeforeRouteUpdate ve onBeforeRouteLeave mevcuttur ancak beforeRouteEnter'ın eşdeğeri yoktur.

Global guard ile meta tabanlı yükleme:

router.beforeResolve(async (to) => {
  if (to.meta.yukle) {
    try {
      await to.meta.yukle(to)
    } catch (e) {
      return { name: 'hata' }
    }
  }
})

beforeResolve, tüm bileşen içi guard'lar çalıştıktan sonra tetiklenir. Bu, veri yükleme gibi yan etkiler için beforeEach'ten daha uygun bir yerdir.

Kaydırma Davranışı ve Geri Dönüş Konumu

Vue Router, scrollBehavior ile sayfa geçişlerinde kaydırma konumunu yönetmenize izin verir.

const router = createRouter({
  history: createWebHistory(),
  routes,
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    }
    if (to.hash) {
      return { el: to.hash, behavior: 'smooth' }
    }
    return { top: 0 }
  },
})

savedPosition yalnızca tarayıcının geri/ileri düğmeleriyle yapılan gezinmelerde dolu gelir. Sayfa içi bağlantılarda (#bolum) to.hash üzerinden hedefe kaydırmak, sabit başlıklı (sticky header) tasarımlarda top ofseti gerektirebilir.

Yaygın Hatalar

  • Guard içinde next() ile return karıştırmak: Vue Router 4'te ikisini aynı guard'da kullanmak tanımsız davranışa yol açar. Birini seçin.
  • addRoute sonrası yeniden eşleştirmeyi unutmak: Aktif URL aynı kaldığı sürece yeni rota devreye girmez.
  • Parametre değişimini izlememek: Aynı bileşen farklı parametreyle açıldığında veri güncellenmez.
  • Guard'da ağır iş yapmak: Her navigasyonda çalışan beforeEach içinde senkron, uzun süren işlemler tüm gezinmeyi yavaşlatır.
  • İstemci guard'ını güvenlik sanmak: meta.requiresAuth yalnızca UX katmanıdır; API tarafında yetki kontrolü şarttır.

Kapsam Notu

Buradaki örnekler Vue Router 4 API'sine dayanır (createRouter, addRoute, removeRoute, beforeResolve). Vue Router 3 ile new VueRouter() ve router.addRoutes() gibi farklı imzalar kullanılır; sürümler arası geçişte bu farkları göz önünde bulundurun.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz