Vue.js Composition API: Kapsamlı Rehber
Vue 3 ile gelen Composition API özelliklerini detaylı olarak inceleyelim ve nasıl kullanacağımızı öğrenelim
Vue.js Composition API: Kapsamlı Rehber
Vue 3 ile birlikte gelen Composition API, Vue.js'de component logic'i organize etmenin yeni ve güçlü bir yolunu sunuyor. Bu yazıda Composition API'nin temellerinden ileri seviye kullanımına kadar her şeyi ele alacağız.
Composition API Nedir?
Composition API, Vue bileşenlerinde mantığı organize etmek için function-based bir yaklaşım sunar. Options API'ye alternatif olarak geliştirilmiş ve özellikle büyük projelerde kod tekrarını azaltır ve mantığı daha iyi organize etmeyi sağlar.
Temel Avantajları
- Daha İyi Logic Reuse: Mantığı farklı bileşenler arasında kolayca paylaşabilirsiniz
- TypeScript Desteği: Daha iyi tip güvenliği
- Daha Esnek Organizasyon: İlgili mantığı bir arada tutabilirsiniz
- Tree-shaking: Kullanılmayan kodları otomatik olarak temizler
Temel Kullanım
setup() Fonksiyonu
Composition API'nin kalbi setup()
fonksiyonudur:
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">Artır</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => {
count.value++
}
return {
count,
increment
}
}
}
</script>
Script Setup Syntax
Daha kısa syntax için <script setup>
kullanabilirsiniz:
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">Artır</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
const increment = () => {
count.value++
}
</script>
Reactivity Fundamentals
ref() vs reactive()
ref() - Primitive değerler için:
import { ref } from 'vue'
const count = ref(0)
const message = ref('Merhaba')
// Değere erişim
console.log(count.value) // 0
count.value = 1
reactive() - Objeler için:
import { reactive } from 'vue'
const state = reactive({
count: 0,
message: 'Merhaba'
})
// Doğrudan erişim
console.log(state.count) // 0
state.count = 1
computed() ve watch()
Computed Properties:
import { ref, computed } from 'vue'
const firstName = ref('Eralp')
const lastName = ref('Özcan')
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`
})
Watchers:
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`)
})
// Immediate watch
watch(count, (newValue) => {
console.log('Count:', newValue)
}, { immediate: true })
Lifecycle Hooks
Composition API'de lifecycle hook'ları on
prefix'i ile kullanılır:
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('Component mounted')
})
onUpdated(() => {
console.log('Component updated')
})
onUnmounted(() => {
console.log('Component unmounted')
})
}
}
Composables - Logic Reuse
Composables, mantığı farklı bileşenler arasında paylaşmanın harika bir yoludur:
// composables/useCounter.js
import { ref } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => count.value++
const decrement = () => count.value--
const reset = () => count.value = initialValue
return {
count,
increment,
decrement,
reset
}
}
Kullanımı:
<script setup>
import { useCounter } from '@/composables/useCounter'
const { count, increment, decrement, reset } = useCounter(10)
</script>
Gerçek Dünya Örneği: Todo App
<template>
<div class="todo-app">
<input
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="Yeni todo ekle..."
>
<ul>
<li
v-for="todo in filteredTodos"
:key="todo.id"
:class="{ completed: todo.completed }"
>
<input
type="checkbox"
v-model="todo.completed"
>
<span>{{ todo.text }}</span>
<button @click="removeTodo(todo.id)">Sil</button>
</li>
</ul>
<div class="filters">
<button
v-for="filter in filters"
:key="filter"
@click="currentFilter = filter"
:class="{ active: currentFilter === filter }"
>
{{ filter }}
</button>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const newTodo = ref('')
const todos = ref([])
const currentFilter = ref('All')
const filters = ['All', 'Active', 'Completed']
const addTodo = () => {
if (newTodo.value.trim()) {
todos.value.push({
id: Date.now(),
text: newTodo.value,
completed: false
})
newTodo.value = ''
}
}
const removeTodo = (id) => {
todos.value = todos.value.filter(todo => todo.id !== id)
}
const filteredTodos = computed(() => {
switch (currentFilter.value) {
case 'Active':
return todos.value.filter(todo => !todo.completed)
case 'Completed':
return todos.value.filter(todo => todo.completed)
default:
return todos.value
}
})
</script>
Best Practices
- Mantığı Gruplandırın: İlgili state ve fonksiyonları bir arada tutun
- Composables Kullanın: Tekrar eden mantığı composable'lara çıkarın
- TypeScript Kullanın: Daha iyi developer experience için
- Destructuring: Return edilen değerleri destructure edin
- Naming Convention: Composable'lar için
use
prefix'i kullanın
Sonuç
Composition API, Vue.js'de component logic'i organize etmenin güçlü ve esnek bir yolunu sunar. Özellikle büyük projelerde kod tekrarını azaltır ve maintainability'yi artırır.
Faydalı Kaynaklar
Bu yazıda Composition API'nin temellerini ve pratik kullanımını ele aldık. Sorularınız için benimle iletişime geçebilirsiniz.