tutorial modules getters español ejemplo javascript vue.js vuex

javascript - modules - ¿Puedo llamar a commit desde una de las mutaciones en la tienda Vuex?



vuex modules (7)

Tengo una tienda vuex , como la siguiente:

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 }

Quiero llamar a la mutación: SET_CATEGORIES desde la mutación: SET_PRODUCTS , pero esto me da un error:

projectFilter.js: 22 Uncaught (en promesa) ReferenceError: commit no está definido (...)

Cuál debería ser la forma correcta de hacer esto. store.commit y this.commit , pero estos también dieron errores similares.


¿Y si tengo algún código común que afecta el estado entre múltiples mutaciones, tengo que duplicar el mismo código en todas mis mutaciones? ¿O hay una mejor manera de hacerlo?


Al leer la documentación de Vuex sobre Acciones , está muy claro para qué están hechos.

  • cometer mutaciones en lugar de mutar el estado
  • Puede contener operaciones asíncronas arbitrarias.

Las acciones pueden (no deben ) contener código asíncrono. De hecho, el siguiente ejemplo es correcto.

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

No veo ningún problema en el uso de acciones para realizar múltiples mutaciones.


Cuando ya estás haciendo una mutación, no hay forma de commit otra mutación. Una mutación es una llamada sincrónica que cambia el estado. Dentro de una mutación, no podrá cometer otra mutación.

Aquí está la referencia de la API para Vuex: https://vuex.vuejs.org/en/api.html

Como puede ver, un controlador de mutación recibe solo el state y la payload , nada más. Por lo tanto, se está commit como undefined .

En su caso anterior, puede establecer el PRODUCTO y las CATEGORÍAS como parte del mismo controlador de mutación como un solo compromiso. Puedes probar si el siguiente código funciona:

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

EDITAR: Por favor, consulte la respuesta a continuación, proporcionada por Daniel S. Deboer . El método correcto es cometer dos mutaciones de una sola acción, como se describe en su respuesta.


Edición: Me topé con un problema muy similar y la solución para mí fue utilizar un programa de obtención de vuex: https://vuex.vuejs.org/en/getters.html
Sus categorías son en realidad una versión "computada" de sus productos. Tener categorías como captador le permite mantenerlos sincronizados con los productos y evita duplicar los datos en su tienda.

Por el bien de responder la pregunta en el título, dejo mi respuesta original.
Una alternativa a la solución de Daniel Buckmaster:

const mutations = { SET_PRODUCTS: (state, response) => { state.products = response.data.products this.SET_CATEGORIES(state) }, SET_CATEGORIES: (state) => { state.categories = state.products.map(product => product.category) } }

Como puedes ver, puedes llamar directamente a la mutación. (como dijo Daniel, después de todo, son funciones simples)
Creo que esta es una respuesta más apropiada a la pregunta original: es una forma real de componer mutaciones sin duplicación de código o funciones adicionales


En su caso, debe considerar tener una sola mutación, a saber, SET_PRODUCTS.

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

Nunca deberías tener que llamar a SET_CATEGORIES por separado. ¡Piénsalo! Las categorías solo pueden mutar si se cambian los productos. Y los productos solo pueden cambiar a través de SET_PRODUCTS.


Para compartir código entre mutaciones, debe crear una nueva función que realice el trabajo, que luego puede reutilizar. Afortunadamente, las mutaciones son simplemente funciones antiguas, y podemos pasar el parámetro de state como queramos, por lo que es bastante fácil de hacer.

Por ejemplo:

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) }


Si es absolutamente necesario cometer dos mutaciones, ¿por qué no hacerlo desde una acción? Las acciones no tienen que realizar operaciones asíncronas. Puede desestructurar el método de confirmación en su acción de la misma manera que lo hace con el estado así:

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