# Vue.js ile ilk reaktif bileşen

> jQuery ile DOM manipülasyonundan Vue.js'in veri odaklı yaklaşımına geçiş deneyimimi ve ilk reaktif bileşeni nasıl yazdığımı anlatıyorum.

- Yayın: 2016-04-03
- Kategori: Arayüz
- Etiketler: JavaScript, Vue.js
- Okuma süresi: 3 dk okuma
- Kaynak: https://www.muhammetsafak.com.tr/blog/vue-js-ile-ilk-reaktif-bilesen/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
Uzun süredir JavaScript'i [jQuery ile](/blog/jquery-ile-ajax-sayfayi-yenilemeden-veri-gondermek) yazıyordum. Form gönderimi, DOM güncellemesi, küçük etkileşimler — hepsi `$('#element').html(...)` ile. Çalışıyordu, ama büyüdükçe takip etmesi güçleşen bir kod yığını ortaya çıkıyordu. Bir buton tıklandığında üç farklı yerde DOM güncelleniyor, birinde güncellemeyi unutursanız ekranda tutarsız bir durum kalıyordu.

Birkaç aydır Vue.js'ten bahsedildiğini duyuyordum. Geçen hafta son bir projeye başlamadan önce incelemeye karar verdim. Bu yazıda gördüklerimi paylaşıyorum; ilk izlenim, ilk bileşen.

## Reaktif yaklaşım nedir?

**Reaktif programlama**, veri değiştiğinde arayüzün otomatik olarak güncellenmesi ilkesine dayanır. jQuery ile veri modeli kafanızdayken DOM'u siz güncelliyordunuz; Vue ile DOM'u siz değil, Vue güncelliyor. Siz yalnızca veriyi değiştiriyorsunuz.

Bu küçük bir fark gibi görünebilir, ama pratikte çok şey değiştiriyor.

## İlk adım: kurulum

Vue 1.x şu an güncel sürüm. Script etiketi ile sayfaya eklemek için CDN yeterli:

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
```

npm ile de kurulabiliyor, ama başlangıç için CDN daha pratik.

## İlk bileşen: basit bir sayaç

En yalın örnek bir sayaçla başlamak:

```html
<div id="uygulama">
    <p>Sayı: {{ sayi }}</p>
    <button v-on:click="artir">Artır</button>
    <button v-on:click="azalt">Azalt</button>
</div>

<script>
new Vue({
    el: '#uygulama',

    data: {
        sayi: 0
    },

    methods: {
        artir: function () {
            this.sayi++;
        },
        azalt: function () {
            this.sayi--;
        }
    }
});
</script>
```

`data` içindeki `sayi` değiştiğinde, `{{ sayi }}` ifadesini içeren DOM elemanı otomatik güncelleniyor. jQuery ile yazıyor olsaydım:

```javascript
// jQuery versiyonu
var sayi = 0;

$('#artir').click(function () {
    sayi++;
    $('#sayac').text('Sayı: ' + sayi);
});

$('#azalt').click(function () {
    sayi--;
    $('#sayac').text('Sayı: ' + sayi);
});
```

DOM güncellemesini ben yapmak zorundayım. Vue'da ise yalnızca `this.sayi++` yazmak yeterli; geri kalanını Vue hallediyor.

jQuery versiyonunda gizli bir tuzak da var: `sayi` değişkeni global kapsamda yaşıyor ya da closure ile sarılması gerekiyor. Birden fazla sayaç olduğunda bu durum hızla karmaşıklaşıyor. Vue'da her bileşenin `data` fonksiyonu kendi kapalı kapsamını getiriyor; bileşenler birbirinin verisine karışmıyor.

## Biraz daha gerçekçi: liste filtresi

Sayaç örneği iyiydi ama bir şey öğretmiyor. Gerçek bir arayüz parçası deneyelim — aranabilir bir liste:

```html
<div id="uygulama">
    <input v-model="arama" placeholder="Ara...">

    <ul>
        <li v-for="urun in filtreliUrunler">{{ urun.ad }}</li>
    </ul>

    <p v-if="filtreliUrunler.length === 0">Sonuç bulunamadı.</p>
</div>

<script>
new Vue({
    el: '#uygulama',

    data: {
        arama: '',
        urunler: [
            { ad: 'Klavye' },
            { ad: 'Mouse' },
            { ad: 'Monitör' },
            { ad: 'Kulaklık' }
        ]
    },

    computed: {
        filtreliUrunler: function () {
            var arama = this.arama.toLowerCase();
            return this.urunler.filter(function (urun) {
                return urun.ad.toLowerCase().indexOf(arama) !== -1;
            });
        }
    }
});
</script>
```

`v-model` input değerini `arama` verisiyle iki yönlü bağlıyor. Computed property olan `filtreliUrunler`, `arama` değiştiğinde otomatik yeniden hesaplanıyor. `v-for` ise listeyi Vue'nun yönetimine bırakıyor.

Bunu jQuery ile yazmak zor değil elbette, ama her şeyi kendiniz bağlamak zorundasınuz: input event'ı dinle, listeyi filtrele, mevcut li elemanlarını temizle, yenilerini oluştur, DOM'a ekle.

Hesaplanmış özellikler burada önemli bir fark yaratıyor. `computed` bloğundaki değer, bağımlı olduğu veri değişmediği sürece önbellekten (cache) okunuyor. Yani her tuş vuruşunda `filtreliUrunler` sıfırdan hesaplanmıyor; `arama` değiştiğinde yeniden hesaplanıyor. Küçük bir liste için bu fark hissedilmez, ama liste büyüdükçe önemli oluyor.

## Gözlemlerim

Vue'nun öğrenme eğrisi düşük. Mevcut bir HTML sayfasına `<script>` ile ekleyip hemen kullanmaya başlayabiliyorsunuz. Bu, tüm projeyi baştan yazmak zorunda kalmadan kademeli olarak benimsemeye izin veriyor; bu benim için önemli bir artı.

`v-bind`, `v-on`, `v-if`, `v-for` gibi directive'ler HTML içinde açık ve okunabilir. Bir şablon dosyasına bakınca ne yapıldığı hızlıca anlaşılıyor.

Olumsuz yanda: büyük projelerde bileşenler arası state yönetimi nasıl işleyecek, henüz tam göremedim. İki ayrı bileşenin aynı veriye ihtiyacı olduğunda ne yapacağım sorusu hâlâ açık. Şimdilik küçük ve orta ölçekli arayüz parçaları için çok tatmin edici.

Önümüzdeki haftalarda component'leri ve Vue Router'ı incelemeyi düşünüyorum.
