Vue.js mülakatlarında karşılaşabileceğiniz, temel bilgilerden mimari kararlara kadar uzanan 10 kritik soruyu ve beklenen cevapları derledim.
1 Vue 2 ile Vue 3 Reactivity Sistemi Arasındaki Fark Nedir?
En temel fark, kullanılan JavaScript teknolojisidir. Vue 2, Object.defineProperty (Getters/Setters) kullanırken, Vue 3 modern tarayıcılarda bulunan Proxy API'sini kullanır.
Vue 2 Kısıtlamaları (Object.defineProperty):
- Sonradan eklenen property'leri algılayamaz (
Vue.setgerekir). - Array indeks değişimlerini ve
lengthdeğişimini doğrudan algılayamaz. - Büyük veri setlerinde başlangıçta (initialization) tüm property'leri gezdiği için performans maliyeti vardır.
Vue 3'teki Proxy tabanlı sistem ise nesnenin kendisine bir "vekil" atar. Bu sayede:
- Dinamik olarak eklenen property'ler otomatik olarak reaktiftir.
- Array manipülasyonları sorunsuz çalışır.
- Lazy Reactivity: İç içe nesneler sadece erişildiğinde reaktif hale getirilir, bu da büyük performans artışı sağlar.
2 Composition API vs Options API: Neden Tercih Edilmeli?
Options API (data, methods, mounted) küçük ve orta ölçekli projeler için harikadır ve öğrenmesi kolaydır. Ancak proje büyüdükçe şu sorunlar ortaya çıkar:
- Kod Dağınıklığı: Bir özellikle (feature) ilgili kodlar dosyanın her yerine dağılır.
- Mantık Paylaşımı Zorluğu: Mixins kullanımı "naming collision" ve veri kaynağı belirsizliği yaratır.
- TypeScript Desteği:
thisbağlamı nedeniyle TS entegrasyonu zordur.
Composition API'nin Avantajları:
// useUserFeature.ts (Composable)
export function useUserFeature() {
const user = ref(null)
const fetchUser = async () => { /* ... */ }
onMounted(fetchUser)
return { user, fetchUser }
}
// Component içinde sadece import edip kullanırsınız.
// Mantık UI'dan tamamen ayrılmış olur.
Bir geliştirici olarak, Composable yapısı sayesinde iş mantığını (business logic) tekrar kullanılabilir, test edilebilir ve modüler hale getirebildiğimiz için Composition API'yi tercih ederim.
3 Vue Yaşam Döngüsü (Lifecycle) Sıralaması Nasıldır?
Bir Vue bileşeni oluşturulurken şu aşamalardan geçer:
- Creation (Oluşturma):
beforeCreate->created(Options API) /setup()(Composition API). Veri gözlemi ve olaylar başlatılır. DOM henüz yoktur. - Mounting (Montaj):
beforeMount->mounted. Şablon derlenir ve DOM'a yerleştirilir. API istekleri genellikle burada yapılır. - Updating (Güncelleme):
beforeUpdate->updated. Reaktif veri değiştiğinde tetiklenir. - Unmounting (Yok Etme):
beforeUnmount->unmounted. Bileşen DOM'dan silinmeden hemen önce ve sonra. Event listener'ları temizlemek için idealdir.
created ve beforeCreate yoktur; bunların yerine doğrudan setup() fonksiyonunun gövdesi kullanılır. 4 Computed vs Watch: Hangisi Ne Zaman Kullanılır?
Computed (Hesaplanmış Özellikler)
Mevcut veriden yeni bir veri türetmek için kullanılır.
- Cache mekanizması vardır (bağımlılık değişmedikçe tekrar hesaplanmaz).
- Senkron çalışmalıdır, side-effect (API isteği vb.) içermemelidir.
- Örn: Filtrelenmiş liste, tam ad (ad + soyad).
Watch (İzleyiciler)
Veri değişimine tepki olarak bir yan etki (side effect) gerçekleştirmek için kullanılır.
- Cache yoktur, her değişimde çalışır.
- Asenkron işlemler (API çağrısı, timer) yapılabilir.
- Örn: Arama kutusu değişince API'ye istek atmak.
5 Büyük Ölçekli Uygulama Mimarisi Nasıl Kurulur?
Büyük bir Vue projesinde sürdürülebilirlik için şu prensipleri uygularım:
- Modüler Yapı (Domain Driven Design): Dosyaları teknolojiye göre (components, views) değil, özelliğe göre (modules/auth, modules/cart) klasörlerim.
- Composables: İş mantığını UI'dan ayırarak
composablesklasöründe toplarım. - Global State Yönetimi (Pinia): State'i modüler store'lara bölerim.
- Base Components: Buton, Input gibi temel UI elemanlarını
BaseButton.vuegibi global bileşenler haline getiririm. - Layout Sistemi: Farklı sayfa yapıları (Admin, User, Auth) için Nuxt veya Vue Router layout sistemini kullanırım.
6 Vue Performansını Artırmak İçin Neler Yaparsın?
- Code Splitting / Lazy Loading: Rotaları ve ağır bileşenleri (
defineAsyncComponent) sadece ihtiyaç duyulduğunda yüklerim. - v-show vs v-if: Sık değişen (toggle) elementler için
v-show(CSS display:none), nadir değişenler içinv-ifkullanırım. - v-for Key: Listelerde her zaman unique (benzersiz) bir
:keykullanırım (index kullanmaktan kaçınırım). - KeepAlive: Sekmeler arası geçişte bileşen durumunu korumak ve tekrar render etmemek için
<KeepAlive>kullanırım. - Virtual Scrolling: Binlerce satırlık listeler için sadece görünen kısmı render eden kütüphaneler (vue-virtual-scroller) kullanırım.
7 Virtual DOM Nasıl Çalışır?
Virtual DOM, gerçek DOM'un bellekteki hafif bir kopyasıdır (JavaScript nesnesi).
- Veri değiştiğinde, Vue yeni bir Virtual DOM ağacı oluşturur.
- Eski ağaç ile yeni ağaç karşılaştırılır (Diffing Algorithm).
- Sadece değişen kısımlar (farklar) hesaplanır.
- Bu farklar gerçek DOM'a uygulanır (Patching).
Bu yöntem, maliyetli olan "doğrudan DOM manipülasyonu" sayısını minimize ederek performansı artırır.
8 Component Communication Yöntemleri Nelerdir?
- Props (Parent -> Child): Veri aktarımı için.
- Emits (Child -> Parent): Olay bildirimi için.
- Provide / Inject (Ancestor -> Descendant): Prop drilling (veriyi torunun torununa taşımak) sorununu çözmek için. Aile ağacında veri paylaşımı sağlar.
- Global State (Pinia/Vuex): Uygulamanın herhangi bir yerinden erişilmesi gereken veriler (Kullanıcı oturumu, sepet) için.
- Refs / Template Refs: Parent'ın Child metodunu doğrudan çağırması gerektiğinde (nadiren kullanılmalı).
9 Vuex'te Mutation ile Action Arasındaki Fark Nedir?
Bu ayrım Vuex'e özgüdür (Pinia'da kaldırılmıştır, her şey Action'dır).
- Mutation: State'i değiştiren tek yerdir. Tamamen senkron (eşzamanlı) çalışmak zorundadır. Devtools takibi için bu şarttır.
- Action: İş mantığını içerir, asenkron olabilir (API isteği). State'i doğrudan değiştirmez, bir Mutation'ı
commiteder.
10 Route-Level Code Splitting Nasıl Uygulanır?
Uygulamanın açılış hızını artırmak için, kullanıcının o an görmediği sayfaların JavaScript kodlarını yüklememek gerekir. Vue Router'da bu işlem dinamik import ile yapılır:
const routes = [
{
path: '/',
component: Home // Statik import (Bundle'a dahil)
},
{
path: '/dashboard',
// Dinamik import (Ayrı bir chunk dosyası oluşturur)
// Sadece kullanıcı bu rotaya girdiğinde yüklenir.
component: () => import('./views/Dashboard.vue')
}
]
Webpack veya Vite, bu sözdizimini gördüğünde otomatik olarak o bileşeni ayrı bir JS dosyasına (chunk) böler.