Vuex Rehberi, Nedir, Nasıl Kullanılır?

Vuex tıpkı Facebook tarafından geliştirilen ve daha sonrasında topluluk tarafından devam ettirilen veri yönetimi kütüphaneleri gibi(Flux, Redux), karmaşık süreçleri daha merkezi ve yönetilebilir kılmayı hedefleyen, Vue’nun da yaratıcısı tarafından geliştirilen bir kütüphanedir.

Öncelikle başlangıç için parcel ile oluşturduğum bir geliştirici ortamı mevcut ve github üzerinden erişebilirsiniz. Repo’yu kendi yerel ortamınıza çektikten sonra “package.json” içerisinde 3 adet komut göreceksiniz.

package.json

Start komutu ile 5000 portunda Vue app’inizi ayaklandırıp aynı zamanda watch edilebilen bir hale büründürüyorsunuz.

Watch index.html içierisindeki assetleri izliyor ve değişiklik anında kendini tekrardan çalıştırıyor.

Build ile işiniz bittiğinde çıktı alıyorsunuz. Asset’leriniz üzerinde doğrudan bir minify işlemi uyguluyor.

Uygulamamız şu an için basit iki dosyadan oluşmakta. App.vue ve main.js.

App’in genel görünümü

“npm i vuex -S” komutu ile uygulamamız içerisine vuex kütüphanesini dahil ediyoruz. Sonrasında “src” klasörünü içerisine, ki burası app’imizin bulunduğu ana dizindir, store adında bir klasör açıp içerisine de vuex değişkenlerimizi ve fonksiyonlarımızı tutacağımız store.js adlı dosyayı oluşturuyoruz.

Klasör yapısı

Sonrasında yapmamız gereken main.js dosyamıza oluşturduğumuz store’u import etmek ve Vue objemize bir property olarak yerleştirmek. Böylelikle uygulamamızın render edildiği her noktada store değişkenlerine ve metodlarına erişim sağlayabileceğiz.

store: store yerine ES özelliklerinden faydalınılarak obje içerisine property’i geçerken eğer atanacak olan değişkenle aynı isimdeyse sadece store yazmak yeterli olacaktır.

Şu durumda içi boş bir store’umuz var ve o store’a artık uygulamanın herhangi bir yerinden erişebiliyoruz. Vuex store’unu oluşturalım.

Burada yaptığımız; öncelikle Vuex kütüphanesini dahl ediyoruz. Sonrasında dahil ettiğimiz bu Vuex kütüphanesini/modülünü alıp Vue’ya kullanması için talimat veriyoruz. Daha sonrasında ise uygulamamızın herhangi bir yerinden erişip yönetebileceğimiz değiken ve metodlardan oluşan sıfını oluşuruyoruz. Burada Vuex.Store sınıfının içinde kullanabileceğimiz önem teşkil eden 4 adet metod söz konusu. Görselde de varolan state, getters, mutations ve actions olmak üzere uygulamamız içerisinde veri akşını sağlamak ve yönetilebilir bir store oluşturmak için kullanacağımız metodlar.

Yukarıdaki görseldeki gibi oluşturduğumuz store’da elimizde sadece state var ve bu tanımlanan state’i App.vue içerisinde çağırıp render edebiliriz.

Ufak bir örnekle gösterelim.

App.vue

Öncelikle {{ this.$store.state.firstName }} ile store’dan gelen değişkenimizi dahil ettik. Artık uygulamamız içerisinde render edilebiliyor.

Store üzerinde değişiklik yaratabilmek adına input ve button oluşturduk. input’da bir değişiklik olduğunda data içerisindeki value güncelleniyor ve biz butonu tetiklediğimizde changeName fonksiyonu çalışarak store içerisindeki firstName state’ini güncelliyor. Dolayısıyla uygulama içerisinde render edilen state’de değişmiş oluyor. Oldukça basit ve temel haliyle bir component’i store ile ilişkiye sokmuş olduk.

Store içerisinde kullanileceğimiz bir başka yöntem ise getters’lar. Getters kabaca state ve diğer getters’lardan gelen verileri return ederek yeni bir değer yaratır ve böylelikle bu değeri bağlı olduğu state güncellendikçe günceller ve fazla işlemden kaçarak getters’ları uygulamanızın içerisinde render edebilirsiniz. Benzer örnek üzerinden göstermek gerekirse;

store.js içerisinde ise şöyle bir değişiklik yaptık.

...
state: {
firstName: 'Algun'
},
getters: {
sayHello: (state) => {
return `Welcome, ${state.firstName}`
}
}
...

getters içerisinde kullandığımız sayHello fonksiyonuna parametre olarak state verebiliyoruz. Böylelikle store içerisindeki state’lere erişip onlar üzerinden yeni değerler return edebiliyoruz. Burada yaptığımız firstName’i kullanarak bir karşılama metni hazırlamaktı. Uygulamamız içerisinde input’tan gelen veriyle yine state’i güncelliyoruz. Ancak state’in güncellenmesi ile birlikte getters’da güncelleniyor ve render edilen metin parçacağı içerisindeki isim değişmiş oluyor.

Şu ana kadar yaptığımız işlemleri App.vue içerisindeki metod ile yapıyorduk. Peki bu metod/fonksiyonları da store içerisinde tutarak daha modüler ve dağıtılabilir bir yapıya büründürmek istersek? Burada devreye mutations ve actions’lar giriyor. Aslında state ve getters’a göre biraz daha karmaşık dursa da store mantığını oturttuktan sonra kullanması çok kolay ve keyifli gelecektir.

Basite indirgeyerek anlatmak gerekirse; elimizde bir mutations var. State’i kullanarak bir değer dönmekten ziyade, doğrudan state üzerinde müdahalede bulunabiliyoruz. Ve dolayısıyla mutations’lara component’lar üzerinden veri gönderebiliyoruz. Dolayısıyla sadece veri çekmek değil karşılıklı bir etkileşim söz konusu. Mutation’larla veri ilişkisine girebilmek içinde store içerisinde onları actions’larla uygulamamız içerisine “commit”liyoruz. En son olarak da herhangi bir component içerisinde this.$store.dispatch(“actions_ismi”, gonderilecek_veri_ismi) şeklinde çağırıp kullanabiliyoruz.

Şimdi bunu bir örnekle pekiştirelim.

Yukarıda anlattığımız işlemleri yan tarafta sırasıyla yaptık. Öncelikle bir mutations yarattık ve mutations içerisinde oluşturduğumuz fonksiyona 2 adet parametre gönderdik. Bunlardan biri state, store içerisindeki state’e erişmesini sağlıyor, diğeri ise payload. Payload ise bizim component üzerinden göndereceğimiz veriyi temsil ediyor. Ve bu veri ile de state içerisindeki firstName’i eşitleyerek state’i güncelledik. Ancak bunu yapabilmek için, component üzerinde veri gönderebilmek için, mutations’ı actions kullanarak uygulamaya commit’lememiz gerekiyordu. Bu aşamada kafa karıştırıcı olmamak adına ufak bir açıklama yapalım. actions içerisinde kullandığımız commit metodu aslında changeName’in aldığı ilk parametre olan context.commit’den geliyor. ES özelliklerini kullanarak doğrudan commit metoduna erişim sağlayabildik. Esasında şu şekilde de kullanılabilir.

changeName (context, payload) {
  context.commit('changeName', payload)
}

Actions da içerisinde benzer payload’i aldı ve tekrardan döndürdü. Böylelikle uygulamamızın içerisindeki herhangi bir bileşenden store objesine doğru bir veri akşını sağlanmış oldu. Bunu ise aşağıda kullanımını göreceğiniz şekilde App.vue içerisinde dispatch kullanarak gerçekleştirdik.

// App.vue
...
<script>
export default {
  name: 'App',
  data() {
    return {
      value: null
    }
  },
  methods: {
    changeName() {
      this.$store.dispatch('changeName', this.value)
    }
  }
}
</script>
...

Temelde store üzerinde oluşturduğumuz fonksiyonlarla yine store üzerinde oluşturduğumuz verileri mutasyona uğrattık ve uygulamamızın herhangi bir yerinde kullanılabilir hale getirdik. Ve bunu yaparken veri akışını tek taraflı değil iki taraflı kıldık.

Anlatımı gözden geçirerek gerekli yerlerde düzeltmelerde bulunan Yiğit Çüküren’e çok teşekkürler.