# Vue Router ile tek sayfa uygulama (SPA) mantığı

> Vue Router ile sayfa geçişlerini istemci tarafına taşırken karşılaştığım temel kavramları ve pratik kurulumu aktarıyorum.

- Yayın: 2016-11-06
- Kategori: Arayüz
- Etiketler: Vue.js
- Okuma süresi: 3 dk okuma
- Kaynak: https://www.muhammetsafak.com.tr/blog/vue-router-ile-tek-sayfa-uygulama-spa-mantigi/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
[Nisan'da Vue.js ile ilk bileşeni yazmıştım](/blog/vue-js-ile-ilk-reaktif-bilesen). O günden bu yana birkaç küçük arayüz parçasında kullandım; reaktif yaklaşım hakkındaki olumlu izlenimim devam ediyor. Bu sefer daha büyük bir adım: Vue Router ile tam bir tek sayfa uygulama (Single Page Application — SPA) mantığını kurmak.

SPA, tüm sayfa geçişlerinin tarayıcı tarafında gerçekleştiği yaklaşımdır. Sunucu yalnızca başlangıçta tek bir HTML dosyasını ve gerekli varlıkları (JavaScript, CSS) gönderir; bundan sonraki tüm navigasyon JavaScript tarafından yönetilir. Sayfa yenilemesi olmaz, geçişler hızlıdır.

## Vue Router nedir?

**Vue Router**, Vue.js için resmi router kütüphanesidir. URL ile bileşen arasındaki eşleştirmeyi sağlar. `npm` ile kurulabiliyor:

```bash
npm install vue-router
```

## Temel kurulum

Önce component'leri tanımlıyorum — her "sayfa" bir Vue component'i:

```javascript
// components/Anasayfa.js
var Anasayfa = {
    template: '<div><h2>Hoşgeldiniz</h2><p>Ana sayfa içeriği.</p></div>'
};

// components/Hakkimda.js
var Hakkimda = {
    template: '<div><h2>Hakkımda</h2><p>Bu benim sayfam.</p></div>'
};

// components/UrunDetay.js
var UrunDetay = {
    template: '<div><h2>Ürün {{ $route.params.id }}</h2></div>'
};
```

Sonra route'ları tanımlayıp router'ı oluşturuyorum:

```javascript
var rotalar = [
    { path: '/',              component: Anasayfa   },
    { path: '/hakkimda',      component: Hakkimda   },
    { path: '/urunler/:id',   component: UrunDetay  }
];

var router = new VueRouter({
    routes: rotalar
});

var uygulama = new Vue({
    router: router,
    el: '#uygulama'
});
```

HTML tarafında `<router-view>` etiketi, aktif bileşenin nereye render edileceğini belirtiyor:

```html
<div id="uygulama">
    <nav>
        <router-link to="/">Anasayfa</router-link>
        <router-link to="/hakkimda">Hakkımda</router-link>
    </nav>

    <router-view></router-view>
</div>
```

`<router-link>` etiketi standart `<a>` yerine kullanılıyor — bağlantıyı sayfayı yenilemeden yönetiyor.

## URL modu: hash ve history

Varsayılan modda URL'ler `/#/hakkimda` biçiminde görünüyor. Bu `hash modu`dur; sunucu yapılandırması gerektirmez çünkü hash kısmı sunucuya gönderilmez.

Temiz URL'ler (`/hakkimda`) için `history modu` kullanılıyor:

```javascript
var router = new VueRouter({
    mode: 'history',
    routes: rotalar
});
```

Ama bu modda sunucu tarafında bir düzenleme gerekiyor: tüm isteklerin `index.html`'e yönlendirilmesi. Nginx'te şöyle bir yapılandırma gerekiyor:

```nginx
location / {
    try_files $uri $uri/ /index.html;
}
```

Bu olmadan `/hakkimda` adresine doğrudan gidildiğinde sunucu 404 dönüyor. Apache için de benzer bir `.htaccess` kuralı gerekiyor. Bu sunucu yapılandırmasını ilk seferinde atlayıp "neden çalışmıyor?" diye zaman harcadım — SPA'yı ilk kez kuran biri için sıkça yaşanan bir tuzak.

## Dinamik rota parametreleri

Ürün detay sayfası gibi dinamik rotalarda parametre almak için `:id` sözdizimini kullanıyorum:

```javascript
var UrunDetay = {
    template: '<div>Ürün ID: {{ urunId }}</div>',

    computed: {
        urunId: function () {
            return this.$route.params.id;
        }
    },

    created: function () {
        // Sayfa yüklenince veri çekebiliriz
        console.log('Ürün ID:', this.$route.params.id);
    }
};
```

`this.$route.params.id` ile URL'deki `:id` değerine erişiyorum. Bileşen içindeki herhangi bir metottan ya da hesaplanmış özellikten bu değere ulaşabiliyorum.

Dinamik rotalarda dikkat ettiğim bir nokta: aynı bileşen farklı parametrelerle yeniden kullanıldığında Vue bileşeni yeniden oluşturmuyor — parametreler değişiyor. Bu yüzden `created` kancası yalnızca ilk yüklemede çağrılıyor. Parametre değişikliğini yakalamak için `$route`'u izlemek (watch) gerekiyor; bunu ilk başta gözden kaçırdım ve veri güncellenmiyor diye uzun süre aradım.

## Navigasyon: programatik yönlendirme

Bazen bir işlem tamamlandıktan sonra programatik olarak yönlendirmek gerekiyor — örneğin form gönderiminin ardından:

```javascript
var UrunEkle = {
    template: '<button @click="kaydet">Kaydet</button>',

    methods: {
        kaydet: function () {
            // Kaydetme işlemi...

            // Ürün listesine yönlendir
            this.$router.push('/urunler');
        }
    }
};
```

## Gözlemlerim

Vue Router ile SPA kurmak düşündüğümden kolay oldu. Bileşenler ile rotalar arasındaki bağ temiz ve anlaşılır.

Bazı durumlar hâlâ kafamı karıştırıyor: birden fazla parametreli rotalar, nested routes, geçiş animasyonları. Bunları ayrıca incelemem gerekiyor.

Sunucu taraflı render (server-side rendering) konusu da var — SEO için önemli. Şu an için küçük bir yönetim paneli üzerinde SPA mantığını deniyorum, SEO önemli değil. Ama kamuya açık bir uygulama için bu meseleye bakılması gerekiyor.

Vue Router, Vue ekosistemi içinde mantıklı bir sonraki adım. Reaktif bileşenler ile yönlendirmeyi bir araya getirince gerçek bir uygulama iskeleti oluşuyor.
