Tengo un vuex de la tienda, como los siguientes:

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 la mutación: SET_CATEGORIES de la mutación: SET_PRODUCTS, Pero este me da error:

projectFilter.js:22 no detectada (en promesa) ReferenceError: cometer es no definida(…)

Lo que debería ser la forma correcta de hacer esto. Traté de store.commit y this.commit, pero estos también dio errores similares.

InformationsquelleAutor Saurabh | 2016-11-08

9 Comentarios

  1. 32

    Cuando usted está haciendo ya una mutación, no hay manera de commit otra mutación. Una mutación es una llamada sincrónica que cambia el estado. Dentro de una mutación, usted no será capaz de cometer otra mutación.

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

    Como se puede ver, una mutación controlador recibe sólo state y payload, nada más. Por lo tanto, usted está consiguiendo commit como undefined.

    En el caso anterior, se puede definir el PRODUCTO y CATEGORÍAS como parte de la misma mutación controlador como un único commit. Usted puede probar si funciona el siguiente código:

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

    EDICIÓN: por Favor remítase a la respuesta a continuación, prestados por Daniel S. Deboer. El método correcto es cometer dos mutaciones de una sola acción, como se describe en su respuesta.

    • Me pregunto por qué no se permite a cometer una mutación de otra mutación? Algunas mutaciones pueden ser tan atómica que deben ser utilizados por las grandes mutación funciones. En la versión actual, no debería ser mucho duplicación de código debido a esta restricción.
    • Sí, es posible tener una confirmación de otra mutación sin efectos secundarios. Pero la depuración de un estado incorrecto de cambio cuando tenemos las mutaciones de llamar a cada uno de los otros se va a llevar a una muy mala experiencia del desarrollador. Creo que es por eso no es recomendable o permitido. Pero por suerte tenemos esta solución simple – siempre podemos definir una única mutación que hace varios cambios de estado, como se ve en esta pregunta / respuesta.
    • En mi humilde opinión, la respuesta es la siguiente (commit de dos cosas de una acción). Es más limpio y legible.
    • Estoy de acuerdo, la respuesta correcta debe ser la de abajo (commit de dos mutaciones de la acción), proporcionado por Daniel. Voy a poner una nota en mi respuesta anterior, para referirse a la mejor respuesta.
    • ¿por qué este no es el preferido sobre la de Dani respuesta? Pensé que esto era semánticamente más correcta de Vuex punto de vista, ya que la acción está diseñado principalmente para las operaciones asincrónicas.
    • Por lo general, tenemos una mutación controlador de hacerlo sólo una simple y sencilla, cosa a la vez – el conjunto de productos o conjunto de categorías, no tanto. Basado en los requisitos de esta pregunta, tenemos que hacer dos cosas al mismo tiempo. Es mejor empujar esta complejidad en una acción en lugar de una mutación. Las mutaciones son más internos a la tienda y más cerca de los datos reales, mientras que las acciones son las que están expuestos los componentes. Así que es lógico que una acción que hace lo que el componente específicamente quiera.
    • Con respecto a las operaciones asincrónicas, estos dos enfoques son equivalentes, ya que la acción en su totalidad es asincrónica. Una vez que la acción se inicia de forma asincrónica, no importa si se comete dos mutaciones uno después de otro, o llama a una especial mutación controlador que hace dos cosas en la tienda. Es una opción de diseño, pero creo que es mejor mantener esta complejidad más cerca de la componente (en la acción) que manejar más abajo en una mutación.

  2. 67

    Si usted absolutamente debe cometer dos mutaciones, ¿por qué no hacerlo de una acción? Las acciones no tienen que realizar las operaciones asincrónicas. Usted puede desestructurados el método commit en su acción de la misma manera que con el estado así:

    commitTwoThings: ({commit}, payload) => {
      commit('MUTATION_1', payload.thing)
      commit('MUTATION_2', payload.otherThing)
    }
    • Sí, esta debe ser la respuesta.
    • no es correcto – Daniel está a la derecha. Mira mi respuesta para más info.
    • estás en lo correcto.
  3. 22

    Compartir código entre las mutaciones, debe crear una nueva función que realiza el trabajo, que luego se puede reutilizar. Afortunadamente, las mutaciones son simplemente funciones, y podemos pasar la state parámetro alrededor, sin embargo nos gusta, así que esto es muy 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)
    }
  4. 9

    Y si tengo algo de código común que afecta el estado entre las múltiples mutaciones, tengo que duplicar el mismo código en todos mis mutaciones? O hay una mejor manera de hacer eso?

    • El silencio es ensordecedor. Me encantaría una respuesta a esto.
    • ver la respuesta que acaba de crear. No es lo ideal pero es lo mejor que conozco
    • Estoy de acuerdo con Daniel. Las funciones son el camino a la re-utilización de código.
    • Y envolverlos en una mutation-helpers.js módulo o el uso de acciones. Aunque en algunos casos la introducción de una acción es una exageración
    • Yep – una mutación es simplemente una función que toma el estado como un argumento y lo modifica. Se puede declarar como muchas funciones auxiliares como quieras y volver a usarlos.
    • Por favor enviar una respuesta sólo cuando tengas una respuesta. Si quieres preguntar algo, crea un nuevo hilo.

  5. 9

    Para el registro. Para llamar a otras mutaciones de una mutación método de hacer esto de esta manera:

    const mutations = {
        mutationOne(state, payload){
            this.commit("mutationTwo", payload)
        },
        mutationTwo(state, payload){
            console.log("called form another mutation", payload)
        }
    }
    • Es este un nuevo(ish) de la característica de Vuex? Sorprendido de que le tomó dos años y medio para que alguien señale la respuesta correcta.
  6. 5

    La lectura de la Vuex documentación sobre Acciones, es bastante claro de qué están hechos para.

    • cometer mutaciones en lugar de la mutación del estado
    • puede contener operaciones asincrónicas arbitrarias

    Acciones puede (no debe) contienen código asíncrono. De hecho, el ejemplo siguiente es correcto

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

    Yo no veo ningún problema en el uso de las acciones para la realización de múltiples mutaciones.

  7. 2

    En su caso, usted debería considerar la posibilidad de tener una sola mutación, es decir, SET_PRODUCTS.

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

    Usted nunca debería haber ninguna necesidad de llamar SET_CATEGORIES por separado. Pensar en ello! Las categorías sólo pueden mutar si los productos se cambian. Y los productos pueden cambiar sólo a través de SET_PRODUCTS.

  8. 0

    Edit : me topé con una muy similar problema y la solución para mí, fue el uso de un vuex getter :
    https://vuex.vuejs.org/en/getters.html

    Sus categorías es en realidad un «calculada» versión de sus productos. Tener categorías como captador permite mantener sincronizados con los productos y evita la duplicación de los datos en su tienda.

    Por el bien de responder a la pregunta en el título os dejo mi respuesta original.

    Una alternativa a Daniel Buckmaster solución :

    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 usted puede ver, usted puede llamar directamente a la mutación en sí. (como dijo Daniel, son simplemente funciones, después de todo)

    Creo que esta es una más adecuada respuesta a la pregunta original : es una forma real de componer las mutaciones sin la duplicación de código o funciones extra

    • Ejecutar una mutación de la función de no es lo mismo, cometiendo una mutación.
    • Podría usted comentar ? Es que realmente un problema ya que nos están llamando de otra mutación ?
    • Por ejemplo, el manipulador para registrar los plugins no será llamado para la segunda mutación. Lo que significa que la Vue dev tools no se mostrará la segunda mutación en la lista de mutaciones puede «viajar en el tiempo» para.
    • Pero el caso de uso es una única mutación que hace dos cosas. Entiendo tu punto, pero en el caso de que usted no quiere tener un almacén de estado que han desynchronised listas de productos y categorías.
    • La pregunta es acerca de cometer dos diferentes mutaciones. Una mutación que hace varios adelgaza es otro problema de diseño que ya se trataron en Daniel respuesta.
    • Hm, sí, eso es lo que quiero decir por «Una alternativa a Daniel Buckmaster solución». Es mi primera respuesta de StackOverflow, tal vez debería haber comentado su solución en su lugar.
    • Usted no puede opinar sobre los mensajes de otras personas sin embargo, como se lleva el 50 rep. Una respuesta es ok en este caso, lo que pasa es que no le gusta. se debe dejar actuar por el bien de la documentación de todos los modos posibles y alguien podría gustarle y upvote (un upvote ser de 10 puntos, frente a -2 para un dv). No te rindas en LO!
    • De hecho ! Esta conversación me hizo darme cuenta de que una solución a este problema también podría ser tener la categoría de un captador. He editado mi respuesta a explicar un poco. Por favor, hágamelo saber lo que piensa y si debo describir mi razonamiento un poco más.

  9. 0
    import spreeApi from '../../gateways/spree-api'
    //initial state
    const state = {
      products: [],
      categories: []
    }
    
    //mutations
    const mutations = {
     SET_PRODUCTS: (state, {response,commit}) => { //here you destructure the object passed to the mutation to get the response and also the commit function
       state.products = response.data.products
       commit('SET_CATEGORIES') //now the commit function is available
     },
     SET_CATEGORIES: (state) => {
       state.categories = state.products.map(function(product) { return product.category})
     }
    
    }
    
    const actions = {
     FETCH_PRODUCTS: ({commit}, filters) => { //here you destructure the state to get the commit function
       return spreeApi.get('products').then(response => commit('SET_PRODUCTS', {response,commit})) //here you pass the commit function through an object to 'SET_PRODUCTS' mutation
     }
    }
    
    export default {
      state,
      mutations,
      actions
    }

    Esto debería solucionar el problema. Usted puede inyectar la confirmación en su mutación a partir de la acción, de modo que usted puede comprometerse de su mutación. Espero que esto ayude

    • Por favor, añadir alguna explicación a su código: exactamente lo que necesita ser cambiado y por qué? Tenga en cuenta que el OP debe ser capaz de aprender de su respuesta

Dejar respuesta

Please enter your comment!
Please enter your name here