85 votes

Puis-je appeler commit à partir d'une des mutations dans le magasin Vuex

J'ai un vuex magasin, comme suit:

import spreeApi from '../../gateways/spree-api'
// initial state
const state = {
  products: [],
  categories: []
}

// mutations
const mutations = {
 SET_PRODUCTS: (state, response) => {
   state.products = response.data.products
   commit('SET_CATEGORIES')
 },
 SET_CATEGORIES: (state) => {
   state.categories = state.products.map(function(product) { return product.category})
 }

}

const actions = {
 FETCH_PRODUCTS: (state, filters) => {
   return spreeApi.get('products').then(response => state.commit('SET_PRODUCTS', response))
 }
}

export default {
  state,
  mutations,
  actions
}

Je veux l'appeler mutation: SET_CATEGORIES de la mutation: SET_PRODUCTS, Mais cela me donne l'erreur:

projectFilter.js:22 Uncaught (promettre) ReferenceError: s'engager n'est pas défini(...)

Ce qui devrait être correcte pour ce faire. J'ai essayé d' store.commit et this.commit, mais ces a également donné des erreurs similaires.

129voto

Daniel S. Deboer Points 510

Si vous devez absolument commettre deux mutations, pourquoi ne pas le faire à partir d'une action? Les actions ne doivent pas nécessairement exécuter des opérations asynchrones. Vous pouvez déstructurer la méthode commit dans votre action de la même manière que vous le faites avec state, comme ceci:

 commitTwoThings: ({commit}, payload) => {
  commit('MUTATION_1', payload.thing)
  commit('MUTATION_2', payload.otherThing)
}
 

58voto

Mani Points 11600

Lorsque vous êtes déjà fait une mutation, il n'y a aucun moyen d' commit d'une autre mutation. Une mutation est un appel synchrone, ce qui modifie l'état. Au sein d'une mutation, vous ne serez pas en mesure de commettre une autre mutation.

Voici la référence de l'API pour Vuex: https://vuex.vuejs.org/en/api.html

Comme vous pouvez le voir, une mutation gestionnaire ne reçoit qu' state et payload, rien de plus. Par conséquent, vous obtenez commit comme undefined.

Dans votre cas ci-dessus, vous pouvez définir le PRODUIT et les CATÉGORIES dans le cadre de la même mutation gestionnaire comme un seul commit. Vous pouvez essayer si le code suivant fonctionne:

// mutations
const mutations = {
    SET_PRODUCTS_AND_CATEGORIES: (state, response) => {
        state.products = response.data.products
        state.categories = state.products.map(function(product) { return product.category})
    },
    // ...
}

EDIT: Veuillez vous référer à la réponse ci-dessous, fournis par Daniel S. Deboer. La bonne méthode est de commettre deux mutations à partir d'une seule action, comme décrit dans sa réponse.

31voto

Daniel Buckmaster Points 1565

Pour partager du code entre des mutations, vous devez créer une nouvelle fonction qui effectue le travail, que vous pouvez ensuite réutiliser. Heureusement, les mutations sont tout simplement de vieilles fonctions, et nous pouvons passer le paramètre state comme bon nous semble, ce qui est très facile à faire.

Par exemple:

 const mutations = {
 SET_PRODUCTS: (state, response) => {
   state.products = response.data.products
   setCategories(state)
 },
 SET_CATEGORIES: (state) => {
   setCategories(state)
 }
}

function setCategories(state) {
  state.categories = state.products.map(product => product.category)
}
 

14voto

Nacho Points 91

Et si j'ai un code commun qui affecte l'état entre plusieurs mutations, je dois dupliquer le même code sur toutes mes mutations? Ou il y a une meilleure façon de faire ça?

7voto

Wanny Miarelli Points 95

La lecture de la Vuex documentation sur les Actions, il est assez clair que ce qu'ils sont faits pour.

  • commettre des mutations au lieu de la mutation de l'état
  • peut contenir arbitraire des opérations asynchrones

Actions peut (et non doit) contiennent le code asynchrone. En fait, l'exemple suivant est correct

increment (context) {
   context.commit('increment')
}

Je ne vois aucun problème dans l'utilisation des actions permettant d'effectuer de multiples mutations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X