Vuex Store Nedir?

25-01-2021

Vuex state management pattern ve bir kütüphane birleşiminden oluşan global bir veritabanı yapısına sahip bir yapıdır. Her veritabanının nasıl veri çekileceği, kaydedileceği, silineceği gibi bir kullanım şekli vardır. Vuex'te bu işlemlerin nasıl yapılacağını ise Vuex Store belirler. Vuex store ile gelişigüzel veri kayıt işlemi yapılması engellenmiş olur.

Vuejs'te vuex store kullanmadığımız zaman bir component'teki state değişimin bu component ile ilişkili olan diğer component'te state'ini aktarması için event yapısı kullanılmaktadır; fakat event'ler projemiz büyüdüğü zaman karmaşık bir yapıya dönüşmektedir. Bundan dolayı Vuex kütüphanesi geliştirilmiştir.

 


Resimde görüldüğü üzere solda en alt tarafta yer alan bir component vuex store de yer alan bir state bilgisini güncellediğinde, o state bilgisi en sağ alt kısımda yer alan diğer component tarafından otomatik olarak algılanır.

Vuex store yapısı vuejs yapısına çok benzemektedir. Vuejs'ten tek farkı mutations alanının olmasıdır:

Vuex store'daki state Vuejs'teki data değişkenine, actions değişkeni methods değişkenine, getters ise computed değişkenine benzemektedir.


Mutations değişkeni state bilgisini güncellemek için kullanılır. Getters değişkeni state değişkenine erişmek için kullanılır, bundan dolayı getters içerisinde tanımlanmış bir metod'ta state bilgisi güncellenmez!

Actions değişkeni içerisinde tanımlanan metodlar ise veritabanı işlemi ya da api isteği gibi backend isteklerini yapmak için kullanılır. Actions değişkeni içerisindeki metodlar ile mutatitions içerisinde tanımlanmış metodlar çağrılır. Ayrıca mutations commit + state değişikliklerini takip ettiği için vue tools kullanarak bir state'in önceki değerine dönebiliriz. Debugging işlemleri için kullanışlı bir yöntemdir.

Kullanımı aşağıdaki gibidir:

fetchTodos metodunda kullanılan context parametresi, store nesnesinin metodlarına ve özelliklerine erişmek için kullanılmaktadır. Yani context.bir vuex store nesnesidir. commit metodu ile mutations değişkeninde tanımlanmış bir metod çağrılmaktadır.

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
});

ES2015 Argument destructuring ile commit metodunu birden çok kez çağırmak istediğimizde aşağıdaki gibi de kullanabiliriz:

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

Action'lar store.dispatch metodu ile tetiklenmektedir. store.displatch('increment') şeklinde çağrıldığında increment metodu çalışır.

Mutation'lar ise store.commit('increment') şeklinde çağrılmaktadır. Peki neden direk mutation'ları çağırmak yerine action'ları çağırıyoruz? Çünkü Mutationlar sekron (synchronous) olmak zorundadır. Biz örneğin API isteğini mutation'lar içerisinde tanımlanan bir metod ile yapamayız çünkü asekron (asynchronous) işlem mutation metodları ile yapılamaz. Bundan dolayı state güncellemek için en doğru kullanım, asekron olsun ya da olmasın, önce action metodu çağrılır, action metodu da mutations metodunu çağırır. Mutations metodu da state bilgisini günceller. Getters metodları da state bilgisine erişmek için kullanılır. Yani getters metodları içerisinde state update edilmez.

store.dispatch farklı kullanımları:

// dispatch with a payload
store.dispatch('incrementAsync', {
  amount: 10
})

// dispatch with an object
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

Component'ler içerisinde Vuex Store Action metodu çağırmak

Bir component içerisinde action metodu iki farklı yöntemle çağrılabilmektedir: this.$store.dispatch('xxx') veya mapActions helper yöntemi.

mapActions helper ile component içerisinde tanımlanmış metodları store.dispatch çağrısına map eder. Örnekle şu şekilde ifade edebiliriz:

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // map `this.increment()` to `this.$store.dispatch('increment')`

      // `mapActions` also supports payloads:
      'incrementBy' // map `this.incrementBy(amount)` to `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // map `this.add()` to `this.$store.dispatch('increment')`
    })
  }
}

burada methods içerisinde tanımlanan 'increment' metodu aslında $this.store.dispatch('increment') şeklini alır.

Gelişmiş Kullanım

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  },
actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}

Async ve Await Kullanım

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // wait for `actionA` to finish
    commit('gotOtherData', await getOtherData())
  }
}

© 2019 All rights reserved. Codesenior.COM