En Vuex, ¿cuál es la lógica de tener tanto "acciones" como "mutaciones"?
Entiendo la lógica de los componentes que no pueden modificar el estado (lo que parece inteligente), pero tener ambas acciones y mutaciones parece que está escribiendo una función para activar otra función, para luego alterar el estado.
¿Cuál es la diferencia entre "acciones" y "mutaciones", cómo funcionan juntas, y más aún, tengo curiosidad por qué los desarrolladores de Vuex decidieron hacerlo de esta manera?
mutations
yactions
se definted en la documentación vuex como métodos para cambiar el estado. No necesitas una acción para cometer una mutación.Respuestas:
Pregunta 1 : ¿Por qué los desarrolladores de Vuejs decidieron hacerlo de esta manera?
Responder:
Pregunta 2 : ¿Cuál es la diferencia entre "acción" y "mutación"?
Veamos primero la explicación oficial:
Aquí está mi explicación de lo anterior:
fuente
Las mutaciones son sincrónicas, mientras que las acciones pueden ser asincrónicas.
Para decirlo de otra manera: no necesita acciones si sus operaciones son sincrónicas; de lo contrario, impleméntelas.
fuente
Creo que tener una comprensión de las motivaciones detrás de las mutaciones y las acciones le permite a uno juzgar mejor cuándo usar qué y cómo. También libera al programador de la carga de la incertidumbre en situaciones donde las "reglas" se vuelven confusas. Después de razonar un poco sobre sus respectivos propósitos, llegué a la conclusión de que, aunque definitivamente puede haber formas incorrectas de usar acciones y mutaciones, no creo que haya un enfoque canónico.
Primero intentemos entender por qué incluso pasamos por Mutaciones o Acciones.
Estrictamente hablando, puede cambiar
state
directamente desde sus componentes. Elstate
es sólo un objeto de JavaScript y no hay nada mágico que revertir los cambios que realice en ella.Sin embargo, al hacer esto, está dispersando sus mutaciones de estado por todo el lugar. Pierde la capacidad de simplemente abrir un solo módulo que aloja el estado y de un vistazo ver qué tipo de operaciones se pueden aplicar a él. Tener mutaciones centralizadas resuelve esto, aunque a costa de algunas repeticiones.
Creo que si reemplaza algo corto con repetitivo, querrá que el repetitivo también sea pequeño. Por lo tanto, supongo que las mutaciones están destinadas a ser envoltorios muy delgados alrededor de las operaciones nativas en el estado, casi sin lógica comercial. En otras palabras, las mutaciones están destinadas a ser utilizadas principalmente como setters.
Ahora que ha centralizado sus mutaciones, tiene una mejor visión general de sus cambios de estado y, dado que sus herramientas (vue-devtools) también conocen esa ubicación, facilita la depuración. También vale la pena tener en cuenta que muchos complementos de Vuex no miran el estado directamente para rastrear los cambios, sino que dependen de mutaciones para eso. Los cambios "fuera de límite" al estado son invisibles para ellos.
Las acciones, como las mutaciones, también residen en el módulo de la tienda y pueden recibir el
state
objeto. Lo que implica que también podrían mutarlo directamente. Entonces, ¿qué sentido tiene tener ambos? Si razonamos que las mutaciones tienen que mantenerse pequeñas y simples, implica que necesitamos un medio alternativo para albergar una lógica comercial más elaborada. Las acciones son los medios para hacer esto. Y como hemos establecido anteriormente, vue-devtools y los complementos son conscientes de los cambios a través de las mutaciones, para mantener la coherencia debemos seguir usando las mutaciones de nuestras acciones. Además, dado que las acciones deben abarcar todo y que la lógica que encapsulan puede ser asíncrona, tiene sentido que las acciones también se vuelvan asincrónicas desde el principio.A menudo se enfatiza que las acciones pueden ser asíncronas, mientras que las mutaciones generalmente no lo son. Puede decidir ver la distinción como una indicación de que las mutaciones deben usarse para cualquier cosa sincrónica (y acciones para cualquier cosa asincrónica); sin embargo, tendría algunas dificultades si, por ejemplo, necesitara cometer más de una mutación (sincrónicamente) o si necesitara trabajar con un Getter de sus mutaciones, ya que las funciones de mutación no reciben Getters ni Mutations como argumentos ...
... lo que lleva a una pregunta interesante.
Todavía no he encontrado una respuesta satisfactoria a esta pregunta. He visto alguna explicación del equipo central de que encontré discutible en el mejor de los casos. Si resumo su uso, los Getters están destinados a ser extensiones computadas (y a menudo en caché) del estado. En otras palabras, básicamente siguen siendo el estado, aunque eso requiere un cálculo inicial y normalmente son de solo lectura. Al menos así es como se les anima a ser utilizados.
Por lo tanto, evitar que las mutaciones accedan directamente a Getters significa que ahora es necesaria una de tres cosas, si necesitamos acceder desde la primera parte de la funcionalidad ofrecida por la última: (1) los cálculos de estado proporcionados por Getter se duplican en algún lugar que sea accesible a la Mutación (mal olor), o (2) el valor calculado (o el Getter correspondiente) se transmite como un argumento explícito a la Mutación (funky), o (3) la lógica del Getter se duplica directamente dentro de la Mutación , sin el beneficio adicional de almacenamiento en caché como lo proporciona Getter (hedor).
El siguiente es un ejemplo de (2), que en la mayoría de los escenarios que he encontrado parece la opción "menos mala".
Para mí, lo anterior parece no solo un poco complicado, sino también algo "permeable", ya que parte del código presente en la Acción está claramente exudando de la lógica interna de la Mutación.
En mi opinión, esto es una indicación de un compromiso. Creo que permitir que Mutaciones reciba Getters automáticamente presenta algunos desafíos. Puede ser tanto para el diseño de Vuex como para las herramientas (vue-devtools et al), o para mantener cierta compatibilidad con versiones anteriores, o alguna combinación de todas las posibilidades establecidas.
Lo que no creo es que pasar Getters a tus mutaciones tú mismo sea necesariamente una señal de que estás haciendo algo mal. Lo veo simplemente como "parchear" una de las deficiencias del marco.
fuente
computed
salida. Son de solo lectura. Una mejor manera de ver las mutaciones podría ser eliminar laif else
que tiene. Los documentos de vuex dicen que puedes alojar más de 1commit
dentro de una acción. Por lo tanto, sería lógico suponer que podría cometer cierta mutación dependiendo de la lógica. Veo las acciones como una forma de dictar QUÉ mutación disparar.Creo que la respuesta TLDR es que las mutaciones están destinadas a ser sincrónicas / transaccionales. Entonces, si necesita ejecutar una llamada Ajax, o hacer cualquier otro código asincrónico, debe hacerlo en una Acción, y luego cometer una mutación después, para establecer el nuevo estado.
fuente
Las principales diferencias entre acciones y mutaciones:
fuente
De acuerdo con la
docs
Las acciones son similares a las mutaciones , las diferencias son que:
Considere el siguiente fragmento.
fuente
Descargo de responsabilidad: acabo de comenzar a usar vuejs, así que solo soy yo extrapolando la intención del diseño.
La depuración de la máquina del tiempo utiliza instantáneas del estado y muestra una línea de tiempo de acciones y mutaciones. En teoría, podríamos haber tenido
actions
junto con una grabación de establecedores de estado y captadores para describir sincrónicamente la mutación. Pero entonces:mutations
transacciones, pero luego podemos decir que la transacción debe mejorarse en lugar de ser una condición de carrera en las acciones. Las mutaciones anónimas dentro de una acción podrían resurgir más fácilmente este tipo de errores porque la programación asincrónica es frágil y difícil.Compare el siguiente registro de transacciones con mutaciones con nombre.
Con un registro de transacciones que no tiene mutaciones con nombre:
Espero que puedan extrapolar de ese ejemplo la posible complejidad añadida en la mutación asíncrona y anónima dentro de las acciones.
https://vuex.vuejs.org/en/mutations.html
fuente
Mutaciones:
Comportamiento:
En forma de Redux
¿Por qué ambos?
Cuando la aplicación crezca, la codificación y las líneas aumentarán, esa vez debe manejar la lógica en las acciones, no en las mutaciones porque las mutaciones son la única autoridad para cambiar el estado, debe estar lo más limpio posible.
fuente
Esto también me confundió, así que hice una demostración simple.
componente.vue
store.js
Después de investigar esto, la conclusión a la que llegué es que las mutaciones son una convención centrada solo en cambiar los datos para separar mejor las preocupaciones y mejorar el registro antes y después de los datos actualizados. Mientras que las acciones son una capa de abstracción que maneja la lógica de nivel superior y luego llama a las mutaciones adecuadamente
fuente
1.De los documentos :
Las acciones pueden contener operaciones asincrónicas, pero la mutación no.
2. Invocamos la mutación, podemos cambiar el estado directamente. y también podemos en la acción de cambiar estados de esta manera:
las Acciones están diseñadas para manejar otras cosas más, podemos hacer muchas cosas allí (podemos usar operaciones asincrónicas) y luego cambiar el estado enviando la mutación allí.
fuente
¡Porque no hay estado sin mutaciones! Cuando se compromete, se ejecuta una pieza de lógica que cambia el estado de manera previsible. Las mutaciones son la única forma de establecer o cambiar el estado (por lo que no hay cambios directos) y, además, deben ser sincrónicas. Esta solución maneja una funcionalidad muy importante: las mutaciones están iniciando sesión en devtools. ¡Y eso le proporciona una gran legibilidad y previsibilidad!
Una cosa más: acciones. Como se ha dicho, las acciones cometen mutaciones. Por lo tanto, no cambian la tienda, y no hay necesidad de que estos sean sincrónicos. ¡Pero pueden manejar una pieza adicional de lógica asincrónica!
fuente
Puede parecer innecesario tener una capa adicional de
actions
solo para llamarmutations
, por ejemplo:Entonces, si
actions
llamalogout
, ¿por qué no llamar a la mutación en sí?La idea completa de una acción es llamar a múltiples mutaciones desde dentro de una acción o hacer una solicitud Ajax o cualquier tipo de lógica asincrónica que puedas imaginar.
Eventualmente podríamos tener acciones que realicen múltiples solicitudes de red y eventualmente llamen a muchas mutaciones diferentes.
Así que tratamos de eliminar tanta complejidad
Vuex.Store()
como sea posible en nuestroactions
y esto deja nuestromutations
,state
ygetters
más limpio y sencillo y está en consonancia con el tipo de modularidad que hace que las bibliotecas como Vue y reaccionar popular.fuente
He estado usando Vuex profesionalmente durante aproximadamente 3 años, y esto es lo que creo que he descubierto sobre las diferencias esenciales entre acciones y mutaciones, cómo puede beneficiarse de usarlas bien juntas y cómo puede hacer su vida más difícil si No lo uses bien.
El objetivo principal de Vuex es ofrecer un nuevo patrón para controlar el comportamiento de su aplicación: la reactividad. La idea es descargar la orquestación del estado de su aplicación a un objeto especializado: una tienda. Proporciona convenientemente métodos para conectar sus componentes directamente a los datos de su tienda para usarlos a su conveniencia. Esto permite que sus componentes se centren en su trabajo: definir una plantilla, estilo y comportamiento de componentes básicos para presentar a su usuario. Mientras tanto, la tienda maneja la pesada carga de datos.
Sin embargo, esa no es solo la única ventaja de este patrón. El hecho de que las tiendas sean una sola fuente de datos para la totalidad de su aplicación ofrece un gran potencial de reutilización de estos datos en muchos componentes. Este no es el primer patrón que intenta abordar este problema de comunicación entre componentes, pero lo que destaca es que te obliga a implementar un comportamiento muy seguro en tu aplicación, básicamente prohibiendo a tus componentes modificar el estado de estos datos compartidos. y forzarlo a utilizar "puntos finales públicos" para solicitar un cambio.
La idea básica es esta:
Dicho esto, la magia comienza cuando comenzamos a diseñar nuestra aplicación de esta manera. Por ejemplo:
Al final, tenemos una experiencia de usuario que se considera "reactiva". Desde la perspectiva de nuestro usuario, el elemento se ha eliminado de inmediato. La mayoría de las veces, esperamos que nuestros puntos finales funcionen, así que esto es perfecto. Cuando falla, todavía tenemos cierto control sobre cómo reaccionará nuestra aplicación , porque hemos separado con éxito la preocupación del estado de nuestra aplicación front-end, con los datos reales.
No siempre necesitas una tienda, eso sí. Si descubre que está escribiendo tiendas que se ven así:
Para mí, parece que solo está usando la tienda como una tienda de datos, y tal vez se está perdiendo el aspecto de la reactividad, al no permitir que también tome el control de las variables a las que reacciona su aplicación. Básicamente, puede y probablemente deba descargar algunas líneas de código escritas en sus componentes a sus tiendas.
fuente