Vuex

Vuex on vue.js -kirjasto keskitettyyn tilanhallintaan.

Käyttöönotto

Konffataan store

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    profile: undefined
  },
  mutations: {
    profileLoaded(state, profile) {
        state.profile = profile;
    }
  },
  actions: {
    getProfile({commit}){
        // api-kutsu backendiin
        api.getProfile().then(profile => {
            commit('profileLoaded', profile);
        });
    }
  }
})

ja lisätään se Vue -instanssiin

import Vue from 'vue'
import App from './App.vue'
import store from './store.js'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

Storen rakenne

Store muodostuu kolmesta osasta. state on storen tila eli missä data pidetään. mutations ovat tilaa muokkaavia metodeita. actions ovat myös metodeita, mutta niistä on tarkoitus kutsua mutaatioita eikä muokata tilaa suoraan. Niissä voi myös kutsua asynkronisia metodeita.

Mutations

Mutaatiot ovat synkronisia metodeita, joilla muokataan storen tilaa. Ensimmäinen parametri on aina storen tila. Toisena parametrina voi olla dataa.

export default new Vuex.Store({
  state: {
    profile: undefined
  },
  mutations: {
    profileLoaded(state, profile) {
        state.profile = profile;
    },
    clearProfile(state) {
        state.profile = undefined;
    }
  }
})

Mutaatioita kutsutaan commitin kautta.

actions: {
    getProfile({commit}){
        // api-kutsu backendiin
        api.getProfile().then(profile => {
            commit('profileLoaded', profile);
        });
    },
    logout({commit}){
        commit('clearProfile');
    }
}

Actions

Actions -metodit voivat olla asynkronisia. Ne ottavat ensimmäisenä parametrina kontekstin (state ja commit) ja toisena mahdollisesti jotain dataa.

actions: {
    getPosts(context, params){
        if(!context.state.postsLoaded) {
            api.getData(params.start, params.end).then(posts => {
                context.commit('postsLoaded', posts);
            });
        }
    }
}

Monesti voi olla selkeämpää purkaa parametrit

actions: {
    getPosts({ commit, state }, { start, end }) {
        if(!state.postsLoaded) {
            api.getData(start, end).then(posts => {
                commit('postsLoaded', posts);
            });
        }
    }
}

Storen käsittely komponenteista

Vuex lisää komponentteihin kentän $store. Sen commit -metodilla voi kutsua mutaatioita ja dispatch -metodilla actioneita. Tilaan pääsee käsiksi state -kentän kautta.

export default {
    data(){
        return {
            start: new Date(),
            end: new Date()
        }
    }
    computed: {
        posts() {
            return this.$store.state.posts;
        }
    },
    created(){
        this.$store.dispatch('getPosts', { this.start, this.end});
    }
}

Moduulit

Storen voi pilkkoa moduuleihin ja lisätä ne "juuristoren" modules -kenttään

import Blog from './BlogStore.js'
import Profile from './ProfileStore.js'

export default new Vuex.Store({
    state: {

    },
    mutations: {

    },
    actions: {

    },
    modules: {
        blog: Blog,
        profile: Profile
    }
})

Tällöin tilaa luettaessa moduulin nimi tulee staten perään

computed: {
    posts(){
        return this.$store.state.blog.posts;
    }
}