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.
Uzun süredir JavaScript’i jQuery ile 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:
<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:
<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:
// 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:
<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.