web-dev-qa-db-fra.com

Puis-je envoyer des getters dans Vuex

Violon: ici

Je crée une webapp avec Vue 2 avec Vuex. J'ai un magasin, où je veux récupérer les données d'état d'un getter, ce que je veux, c'est si getter découvre que les données ne sont pas encore remplies, il appelle dispatch et récupère les données.

Voici ma boutique Vuex:

const state = {
  pets: []
};

const mutations = {
  SET_PETS (state, response) {
    state.pets = response;
  }
};

const actions = {
 FETCH_PETS: (state) => {
      setTimeout(function() { 
            state.commit('SET_PETS', ['t7m12qbvb/Apple_9', '6pat9znxz/1448127928_kiwi'])
    }, 1000)
 }
}

const getters = {
    pets(state){
    if(!state.pets.length){
        state.dispatch("FETCH_PETS")
    }
    return state.pets
  }
}

const store = new Vuex.Store({
  state,
  mutations,
  actions,
  getters
});

Mais je reçois l'erreur suivante:

TypeError non intercepté: state.dispatch n'est pas une fonction (…)

Je sais que je peux le faire, à partir de beforeMount de Vue, mais j'ai plusieurs composants qui utilisent le même magasin Vuex, donc je dois le faire dans l'un des composants, lequel devrait-il être et comment cela affectera-t-il les autres composants?.

17
Saurabh

Les getters ne peuvent pas appeler dispatch car ils passent le state pas context du magasin

Les actions peuvent appeler état, répartir, valider lorsqu'elles passent le contexte.

Les getters sont utilisés pour gérer un "état dérivé".

Si vous configurez à la place l'état pets sur les composants qui le nécessitent, vous appellerez simplement FETCH_PETS de la racine de votre application et supprimez le besoin de getter

8
GuyC

avait le même problème .. voulait également que toutes les instances de Vue chargent automatiquement quelque chose, et a écrit un mixin:

store.registerModule('session', {
    namespaced: true,
    state: {
        session: {hasPermission:{}},
        sessionLoaded:false
    },
    mutations: {
        changeSession: function (state, value)
        {
            state.session = value;
        },
        changeSessionLoaded: function (state)
        {
            state.sessionLoaded = true;
        }

    },
    actions: {
        loadSession(context)
        {
            // your Ajax-request, that will set context.state.session=something
        }
    }
}); 

Vue.mixin({
    computed: {
        $session: function () { return this.$store.state.session.session; },
    },
    mounted:function()
    {
        if(this.$parent==undefined && !this.$store.state.session.sessionLoaded)
        {
            this.$store.dispatch("session/loadSession");
            this.$store.commit("changeSessionLoaded");
        }
    },
});

car il ne charge qu'un seul par vue-instance et magasin et l'inclut automatiquement dans chaque vue-instance, il n'est pas nécessaire de le définir dans chaque application principale

0
mech