Vue 3, Composition API ile birlikte bileşen mantığını fonksiyon tabanlı bir yapıya taşıdı. Bu rehber, orta seviye geliştiricilerin setup mantığını, reaktif temelleri ve durum yönetimi kararlarını uygulanabilir biçimde kurmasına odaklanır. Amaç, her ölçekte projeye uyabilecek zamana dayanıklı bir zihinsel model oluşturmaktır.
Önkoşullar ve Sürüm Kapsamı
- Vue 3'ün temel bileşen yapısına (template, props, emit) aşinalık.
- JavaScript/TypeScript ve ES modülleri hakkında çalışma bilgisi.
- Node.js ve bir paket yöneticisi (npm, pnpm veya yarn) kurulu bir geliştirme ortamı.
Sürüm notu: Composition API, Vue 3.0 ile çekirdek olarak geldi. <script setup> sözdizimi ise 3.2 ile kararlı hale geldi. Bu rehber bu iki özelliği temel alır; ancak belirli bir yama sürümüne bağlı kalmanız gerekmez. Sürüm numarası gerektiren bir ifade kullanmıyorum; projenizde kullandığınız Vue sürümünün resmi sürüm notlarını doğrulayın.
Composition API'nin Temel Mantığı
Options API'de bir bileşenin verisi, metotları ve yaşam döngüsü ayrı seçenek bloklarına dağılır. Composition API'de ise ilgili mantık tek bir setup kapsamında, fonksiyonlar halinde bir araya getirilir. Bu, özellikle büyüyen bileşenlerde okunabilirliği ve yeniden kullanılabilirliği artırır.
Temel yapı taşları şunlardır:
ref: İlkel değerler için reaktif referans.reactive: Nesneler için reaktif proxy.computed: Türetilmiş, önbelleklenen değer.watch/watchEffect: Yan etkileri tetikleyen izleyiciler.onMounted,onUnmountedgibi yaşam döngüsü kancaları.
Adım Adım: <script setup> ile Reaktif Durum
1. Reaktif referans oluşturma
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
</script>
<template>
<button @click="increment">Artır: {{ count }}</button>
<p>İki katı: {{ double }}</p>
</template>
Beklenen davranış: Butona her tıklamada count bir artar, double otomatik olarak iki katını gösterir. computed yalnızca bağımlılığı (count) değiştiğinde yeniden hesaplanır.
Not: ref ile tanımlanan bir değere script içinde erişirken .value kullanmanız gerekir. Template içinde Vue bunu otomatik olarak açar.
2. Nesneler için reactive ve sınırları
<script setup>
import { reactive } from 'vue'
const form = reactive({
email: '',
password: ''
})
</script>
<template>
<input v-model="form.email" />
<input v-model="form.password" type="password" />
</template>
reactive nesne özelliklerine doğrudan erişim sağlar; .value gerekmez. Ancak reactive ile tanımlanan bir nesneyi tamamen yeniden atamak reaktiviteyi koparır. Bu yüzden form gibi yapılarda reactive, tek bir değerin yerini tutacak durumlarda ref tercih edilir.
3. Yaşam döngüsü ve temizlik
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const width = ref(window.innerWidth)
function onResize() {
width.value = window.innerWidth
}
onMounted(() => window.addEventListener('resize', onResize))
onUnmounted(() => window.removeEventListener('resize', onResize))
</script>
<template>
<p>Pencere genişliği: {{ width }}</p>
</template>
Beklenen davranış: Bileşen ekrana geldiğinde dinleyici eklenir, bileşen kaldırıldığında temizlenir. onUnmounted içindeki temizlik, bellek sızıntılarını önlemek için kritiktir.
Mantığı Yeniden Kullanma: Composable'lar
Composition API'nin en güçlü yanı, durum mantığını composable adı verilen fonksiyonlara taşıyabilmektir. Kural: composable adı use ile başlar ve içinde reaktif API'ler kullanılır.
// useCounter.js
import { ref, computed } from 'vue'
export function useCounter(initial = 0) {
const count = ref(initial)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, double, increment }
}
<script setup>
import { useCounter } from './useCounter'
const { count, double, increment } = useCounter(5)
</script>
Bu yaklaşım, aynı mantığı birden fazla bileşende paylaşmanızı sağlar. Dikkat edilmesi gereken nokta: composable içindeki ref değerlerini dışa aktarırken referansı koruyun; nesneyi parçalayıp yeniden atamak reaktiviteyi bozabilir.
Durum Yönetimi Kararı
Composition API, küçük ve orta ölçekli uygulamalarda çoğu durum yönetimi ihtiyacını karşılar. Ancak birden fazla bileşenin paylaştığı global durum söz konusu olduğunda iki temel yol vardır:
- Paylaşılan composable: Modül düzeyinde tanımlanmış
refdeğerleri, uygulama genelinde tek bir kaynak olarak kullanılabilir. - Resmi durum yönetimi kütüphanesi (Pinia): Vue ekosisteminin önerdiği çözümdür; geliştirici araçları, modüler yapı ve sunucu tarafı render desteği sunar.
Paylaşılan composable örneği
// store/auth.js
import { ref } from 'vue'
const user = ref(null)
export function useAuth() {
function login(userData) {
user.value = userData
}
function logout() {
user.value = null
}
return { user, login, logout }
}
Buradaki user modül düzeyinde tanımlandığı için tüm bileşenler aynı referansı paylaşır. Küçük uygulamalar için yeterlidir; ancak uygulama büyüdükçe modülerlik, hata ayıklama ve test edilebilirlik açısından Pinia gibi bir çözüme geçmek daha sağlıklı olur.
Pinia ile temel kurulum
// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, double, increment }
})
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<button @click="counter.increment">{{ counter.double }}</button>
</template>
Pinia'nın setup sözdizimi, Composition API ile aynı mantığı kullanır; bu da geçişi doğal kılar.
Yaygın Hatalar
refdeğerini template dışında.valueolmadan kullanmak: Script içindecountdeğilcount.valueyazmanız gerekir.reactivenesnesini tamamen yeniden atamak:state = { ... }gibi bir atama reaktiviteyi koparır; bunun yerine nesne özelliklerini güncelleyin veyarefkullanın.watchilewatchEffectfarkını karıştırmak:watchbelirli kaynakları izler ve eski/yeni değerleri verir;watchEffectçalıştığı anda erişilen tüm reaktif bağımlılıkları otomatik izler.- Temizlik yapmamak:
setInterval,addEventListenergibi kaynaklarıonUnmountediçinde serbest bırakmamak bellek sızıntısına yol açar. - Composable içinde
thiskullanmaya çalışmak: Composition API'dethisyoktur; tüm bağımlılıkları açıkça import edin.
Güvenlik ve Sürdürülebilirlik Notları
- Sunucu tarafı render (SSR): Paylaşılan modül düzeyindeki
refdeğerleri, sunucuda istekler arasında sızabilir. SSR kullanıyorsanız durumu istek başına izole etmek için Pinia veya benzeri bir çözüm tercih edin. - Reaktivite ile hassas veri: Parola veya token gibi değerleri reaktif durumda tutmak, geliştirici araçlarında görünmelerine neden olabilir. Bu tür verileri yalnızca gerektiğinde ve mümkünse reaktif olmayan yapılarda saklayın.
- Bağımlılık güncellemeleri: Composition API'nin davranışı sürümler arasında küçük farklılıklar gösterebilir; yükseltme yaparken resmi sürüm notlarını ve kırıcı değişiklikleri takip edin.
Sonuç
Composition API, Vue 3'te durum ve mantığı fonksiyonlar halinde düzenlemenizi sağlar. Küçük uygulamalarda paylaşılan composable'lar yeterli olurken, büyüyen projelerde Pinia gibi resmi bir çözüme geçmek modülerliği ve test edilebilirliği artırır. Reaktivitenin temel kurallarını (.value, reactive sınırları, temizlik) doğru uygulamak, hem hataları azaltır hem de kodunuzu sürüm değişimlerine karşı dayanıklı kılar.