Pinia ile Vue durum yönetimi: store, getter ve action
Pinia ile store tanımlama, state, getter ve action kullanımı, storeToRefs, Vuex'ten geçiş ve sık yapılan hatalar. Vue 3 için örnek kodlarla anlatım.
Durum yönetimi ne zaman gerekir?
Her Vue bileşeni kendi reaktif durumunu zaten yönetir. Sorun, aynı verinin birçok bileşen tarafından okunması ve değiştirilmesi gerektiğinde başlar: oturum açmış kullanıcı, sepet içeriği, tema tercihi, bildirim listesi. Bu veriyi props ve emits zinciriyle bileşenden bileşene taşımak karmaşık ve kırılgan hale gelir.
Pinia, bu ortak durumu bileşenlerin dışında tek bir yerde tutmanızı sağlar. Vue dokümantasyonuna göre Pinia, resmî olarak önerilen durum yönetimi kütüphanesidir; Vuex bakım moduna alınmıştır, çalışmaya devam eder ama yeni özellik almaz ve yeni uygulamalarda Pinia önerilir. Pinia'nın Vuex'e göre daha sade bir API sunduğu, Composition API tarzı yazımı desteklediği ve TypeScript ile güçlü tip çıkarımı sağladığı belirtilir.
Kurulum ve ilk store
Pinia'yı uygulamaya bir kez tanıtırsınız:
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue'
createApp(App).use(createPinia()).mount('#app')
Her store ayrı bir dosyada defineStore ile tanımlanır. Pinia farklı yazım biçimleri sunar. Setup store, Composition API'ye benzer:
// stores/cart.js import { ref, computed } from 'vue' import { defineStore } from 'pinia'
export const useCartStore = defineStore('cart', () => { const products = ref([]) const count = computed(() => products.value.length)
function addItem(product) { products.value.push(product) } function clear() { products.value = [] } return { products, count, addItem, clear } })
Setup store içinde ref'ler state, computed'lar getter, fonksiyonlar ise action olur. Dokümantasyon, durum özelliklerinin hepsinin return ile döndürülmesi gerektiğini vurgular; döndürülmeyen özellik Pinia tarafından state olarak tanınmaz.
Store'u bileşende kullanma ve storeToRefs
Store, bileşenin script setup bölümünde çağrılır:
<script setup> import { storeToRefs } from 'pinia' import { useCartStore } from '@/stores/cart'
const cart = useCartStore() const { products, count } = storeToRefs(cart) const { addItem } = cart </script>
Burada kritik nokta: store reaktif bir nesnedir, bu yüzden özelliklerini doğrudan ayrıştırırsanız (const { count } = cart) reaktiflik kaybolur. Reaktif kalması gereken state ve getter'lar için storeToRefs kullanın. Action'lar ise store'a bağlı fonksiyonlar olduğundan doğrudan ayrıştırılabilir. Şablonda getter'a .value yazmaya gerek yoktur.
State, getter ve action: görevler
State, uygulamanın ham verisidir. Getter, bu veriden türetilen değerdir ve computed gibi önbelleğe alınır; örneğin sepet toplamı, filtrelenmiş liste. Action, durumu değiştiren iş mantığıdır ve bileşenlerdeki metotlara denk gelir. Asenkron işlemler de action içinde yapılır:
async function load() { loading.value = true try { const response = await fetch('/api/cart') products.value = await response.json() } finally { loading.value = false } }
Birden çok alanı aynı anda güncellemeniz gerekiyorsa store üzerindeki $patch metodu kısmi bir state nesnesini ya da bir fonksiyonu kabul eder. Store'u başlangıç değerine döndürmek için option store'larda $reset hazır gelir; setup store'larda bu metodu kendiniz yazarsınız.
Neyi Pinia'ya koymalı, neyi koymamalı?
Pinia'ya yalnızca birden çok bileşenin paylaştığı ve bileşenin ömründen uzun yaşayan durumu koyun: oturum, sepet, bildirimler, kullanıcı tercihleri. Tek bir bileşene ait geçici durumu (açık-kapalı menü, form alanı) ref ile bileşende tutun; her şeyi store'a taşımak bakımı zorlaştırır.
Sunucudan gelen veriyi de aklınızda tutun: sunucu verisinin önbelleği ve yeniden doğrulaması başlı başına bir sorundur. Basit uygulamada Pinia içinde yükleyip saklamak yeterlidir; veri yoğun uygulamalarda ayrı bir veri çekme katmanı düşünülebilir. Store'ları özelliğe göre bölün (kullanıcı, sepet, bildirim) ve her birini ayrı dosyada tutun; bu, paket bölme ve tip çıkarımı için de dokümantasyonun önerdiği yapıdır.
Vuex'ten geçiş
Mevcut bir Vuex uygulaması varsa tek seferde taşımak zorunda değilsiniz; Vuex ve Pinia aynı projede birlikte bulunabilir. Pratik yaklaşım, yeni özellikleri Pinia ile yazmak ve eski modülleri sırayla taşımaktır. Vuex'teki mutation kavramı Pinia'da yoktur; state doğrudan action içinden değiştirilir. Modüller yerine her biri kendi başına duran store'lar kullanılır; store'lar birbirini gerektiğinde çağırarak birleşir.
Taşırken testlerin hazır olması önemlidir; örneğin sepet modülünü taşımadan önce ekleme, boşaltma ve toplam hesabını doğrulayan testler yazın, böylece taşıma sonrası davranışın aynı kaldığını görürsünüz. Bileşenlerde mapState gibi yardımcıları kullanan eski kodu, store'u doğrudan çağıran yeni biçime en son çevirin. Davranışı önce mevcut modül için testle sabitleyin, sonra aynı testi yeni store'a uygulayın.
Sık yapılan hatalar
- Store'u destructure etmek: Reaktiflik kaybolur; storeToRefs kullanın.
- Setup store'da state özelliğini return etmemek: Pinia onu state olarak görmez; devtools ve eklentiler bozulur.
- Her şeyi global store'a koymak: Geçici bileşen durumu store'ları şişirir.
- Getter içinde yan etki yapmak: Getter yalnızca hesaplamalıdır; yan etkiler action'a aittir.
- Store'u bileşen dışında yanlış zamanda çağırmak: Uygulama oluşturulmadan önce çağrılan store hata verir; özellikle yönlendirme korumalarında store'u koruma fonksiyonunun içinde çağırın.
- Tüm store'ları tek dosyada tutmak: Bölme ve test kolaylığı kaybolur.
Mindset programlarında nerede çalışılır?
Vue.js 3 ve Composition API ile Uygulama Geliştirme eğitiminde durum yönetimi ve yönlendirme ayrı bir modül olarak ele alınır; reaktivite, bileşen iletişimi ve kompozisyon fonksiyonları da programın temelini oluşturur. Bu yapı, bileşenler arası veri akışı karmaşıklaşmış bir uygulamada Pinia'ya geçmek isteyen ön yüz geliştiricileri için uygundur.
Kurumsal ekiplerde sıklıkla ortak bir store yapısı ve isimlendirme kuralı belirlemek bakım maliyetini düşürür. Ekibinize özel bir uygulamalı çalışma düşünüyorsanız kurumsal eğitim talebi üzerinden kapsamı belirleyebilirsiniz.
İlgili Mindset programı
Vue.js 3 ve Composition API ile Uygulama Geliştirme
Sık sorulan sorular
Pinia mı Vuex mi kullanmalıyım?
Yeni projelerde Pinia önerilir. Vue dokümantasyonu Vuex'in bakım modunda olduğunu, çalışmaya devam ettiğini ama yeni özellik almayacağını belirtir. Mevcut Vuex projelerini hemen taşımak zorunda değilsiniz; yeni özellikleri Pinia ile yazıp eskileri sırayla taşıyabilirsiniz.
Store'daki state'i doğrudan değiştirebilir miyim?
Evet, Pinia'da store üzerindeki state özelliğine doğrudan değer atayabilirsiniz; Vuex'teki mutation zorunluluğu yoktur. Yine de iş mantığını action içinde toplamak izlemeyi ve testi kolaylaştırır. Birden çok alanı birlikte güncellerken patch metodunu kullanmak, değişikliği tek adımda uygular.
Option store mu setup store mu seçmeliyim?
Pinia dokümantasyonu, Vue'nun Options ve Composition API ayrımına benzer şekilde dilediğinizi seçmenizi söyler. Option store daha yapılandırılmış ve öğrenmesi kolay, setup store ise daha esnektir; store içinde watch ve composable kullanabilirsiniz. Ekip alışkanlığına göre karar verin.
Store'daki veri sayfa yenilenince kaybolur mu?
Evet, Pinia durumu bellekte tutulur ve sayfa yenilenince sıfırlanır. Kalıcı olması gereken veriyi yerel depoya yazıp açılışta store'a geri yükleyebilir ya da sunucudan yeniden çekebilirsiniz. Hassas bilgiyi (kimlik bilgisi gibi) yerel depoya yazarken güvenlik etkisini ayrıca değerlendirin.
Her bileşen için ayrı store mu açmalıyım?
Hayır. Pinia'ya yalnızca birden çok bileşenin paylaştığı durumu koyun. Tek bir bileşene ait geçici durumu ref ile bileşende tutmak daha sadedir. Store'ları bileşene göre değil, özelliğe göre ayırın: kullanıcı, sepet, bildirimler gibi.