Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Vue
Code

Cómo Construir Aplicaciones Complejas y a Gran Escala Vue.js con Vuex

by
Difficulty:AdvancedLength:LongLanguages:

Spanish (Español) translation by James (you can also view the original English article)

Es tan fácil de aprender y usar que cualquiera puede construir una sencilla aplicación con la marco Vue.js. Incluso los novatos, con la ayuda de la documentación de Vue, pueden hacer el trabajo. Sin embargo, cuando la complejidad entra en juego, cosas se ponen un poco más serias. La verdad es que múltiples componentes profundamente anidados con estado compartido pueden convertirse rápidamente su aplicación en un caos insostenible.

El principal problema en una aplicación compleja es cómo administrar el estado entre componentes sin escribir código spaghetti o producir efectos secundarios. En este tutorial usted aprenderá a resolver el problema mediante el uso de Vuex: una biblioteca de administración de estado para la construcción de aplicaciones complejas de Vue.js.

¿Qué es Vuex?

Vuex es una biblioteca de gestión de estado sintonizada específicamente para la construcción de aplicaciones complejas a gran escala Vue.js. Usa una tienda global y centralizada para todos los componentes en una aplicación, aprovechando su sistema de reactividad para las actualizaciones de inmediatas.

La tienda de Vuex está diseñada de tal manera que no es posible cambiar su estado de cualquier componente. Esto asegura que el Estado sólo puede ser transformado en una manera predecible. Su tienda se convierte así en una única fuente de verdad: cada elemento de datos se almacena sólo una vez y es de sólo lectura para evitar que los componentes de la aplicación corrompiendo el estado el que se accede por otros componentes.

¿Por qué necesita Vuex?

Usted puede preguntar: ¿por qué necesito Vuex en primer lugar? ¿No puedo solo ponga el estado compartido en un archivo de JavaScript normal e importarlos a mi solicitud Vue.js?

Usted puede, por supuesto, pero en comparación con un simple objeto global, la tienda de Vuex tiene algunas importantes ventajas y beneficios:

  • La tienda de Vuex es reactiva. Una vez que los componentes recuperan un estado de él, reactivo para actualizar sus puntos de vista cada vez los cambios de estado.
  • Componentes directamente no pueden mutar estado de la tienda. La única manera de cambiar el estado de la tienda es comprometiéndose explícitamente las mutaciones. Esto asegura que cada cambio de estado deja un récord con seguimiento, que hace más fácil de depurar y probar la aplicación.
  • Fácilmente puede depurar su aplicación gracias a la integración de Vuex con la extensión de Vue DevTools.
  • La tienda de Vuex le da una vista panorámica de cómo todo está conectado y afectada en su aplicación.
  • Es más fácil mantener y sincronizar el estado entre varios componentes, incluso si cambia la jerarquía de componentes.
  • Vuex permite la comunicación directa entre componentes.
  • Si un componente es destruido, el estado en la tienda de Vuex permanecerá intacto.

Introducción a Vuex

Antes de empezar, quiero aclarar varias cosas.

En primer lugar, para seguir este tutorial, usted necesita tener una buena comprensión de Vue.js y su sistema de componentes o por lo menos mínima experiencia con el marco.

También, el objetivo de este tutorial es no para mostrarte cómo crear una aplicación compleja real; el objetivo es enfocar su atención más en los conceptos de Vuex y cómo usted puede utilizar para crear aplicaciones complejas. Por esa razón, voy a utilizar ejemplos muy llano y simples, sin ningún código redundante. Una vez que usted comprender completamente los conceptos de Vuex, podrás aplicar en cualquier nivel de complejidad.

Finalmente, lo voy usando sintaxis ES2015. Si no está familiarizado con él, usted puede aprender aquí.

Y ahora, vamos a empezar!

Creación de un Proyecto de Vuex

El primer paso para empezar con Vuex es que Vue.js y Vuex instalado en su máquina. Hay varias maneras de hacerlo, pero vamos a usar uno más fácil. Crear un archivo HTML y añadir los enlaces necesarios de la CDN:

Usé algunos CSS para que los componentes se vean mejor, pero usted no tiene que preocuparse acerca de ese código CSS. Que sólo le ayuda a obtener una idea visual sobre lo que está pasando en el. Solo copiar y pegar lo siguiente dentro de la <head> etiqueta:

Ahora, vamos a crear algunos de los componentes para trabajar con. Dentro de la<script></script> etiqueta, coloca el siguiente código Vue:

Aquí tenemos una instancia de Vue, un componente de la matriz y dos componentes de niño. Cada componente tiene un encabezado "Score:" donde te salida el estado de la aplicación.

La última cosa que necesita hacer es poner un envoltorio <div> con id="app" derecho después de la apertura <body> y coloque el componente de la matriz interior:

Ahora se realiza el trabajo de preparación, y ya estamos listos para seguir adelante.

Explorar Vuex

Gestión de Estato

En la vida real, nos ocupamos de complejidad mediante el uso de estrategias para organizar y estructurar el contenido que deseamos utilizar. Grupo de cosas relacionadas en diferentes secciones, categorías, etcetera. Es como una biblioteca de libros, en que los libros son clasificados y en diferentes secciones que podemos encontrar fácilmente lo que estamos buscando. Vuex arregla los datos de la aplicación y la lógica relacionada con estado en cuatro grupos o categorías: Estado, captadores, mutaciones y acciones.

Estado y las mutaciones son la base para cualquier tienda de Vuex:

  • Estado es un objeto que contiene el estado de los datos de aplicación.
  • mutaciones también es un objeto que contiene métodos que afectan el estado.

Captadores y acciones son como proyecciones lógicas de estado y de las mutaciones:

  • getters contienen los métodos utilizados para abstraer el acceso al estado y para hacer algunas tareas de preprocesamiento, si es necesario (cálculo de datos, filtrado, etcetera).
  • acciones son métodos utilizados para provocar mutaciones y ejecutar código asíncrono.

Vamos a explorar el siguiente diagrama para hacer las cosas un poco más claras:

Vuex State Management Workflow Diagram

En el lado izquierdo, tenemos un ejemplo de una tienda de Vuex, que vamos a crear más adelante en este tutorial. A la derecha, tenemos un diagrama de flujo de trabajo de Vuex, que muestra cómo los diferentes elementos Vuex trabajaran juntos y comunican entre sí.

Para cambiar el estado, un particular componente Vue debe comprometerse las mutaciones (por ejemplo este. $store.commit('increment', 3)), y luego, ésos mutaciones cambian el estado (score se convierte en 3). Después de eso, los captadores se actualizan automáticamente gracias al sistema reactivo de Vue y hacen las actualizaciones en la vista del componente (con this.$store.getters.score).

Las mutaciones no pueden ejecutar código asíncrono, ya que esto hace imposible al registro y seguimiento de los cambios en las herramientas de depuración como Vue DevTools. Para usar la lógica asincrónica, necesita poner en acciones. En este caso, un componente primero enviar acciones (this.$store.dispatch('incrementScore', 3000)) donde se ejecuta el código asíncrono, y luego esas acciones comprometerá las mutaciones, que mutan el estado.

Crear un Esqueleto de Tienda Vuex

Ahora que nos hemos explorado cómo funciona Vuex, vamos a crear el esqueleto de nuestra tienda Vuex. Poner el siguiente código sobre el registro de componente ChildB:

Para proporcionar acceso global a la tienda de Vuex de cada componente, es necesario agregar la propiedad de store en la instancia de Vue:

Ahora, podemos acceder a la tienda de cada componente con el this.$store variable.

Hasta ahora, si abre el proyecto con CodePen en el explorador, verá el siguiente resultado.

App Skeleton

Propiedades de Estado

El objeto de estado contiene todos los datos compartidos en su aplicación. Por supuesto, si es necesario, cada componente puede tener su propio estado privado también.

Imagine que desea crear una aplicación de juego, y necesita una variable para almacenar el resultado del juego. Lo pones en el objeto del estado:

Ahora, usted puede acceder a puntuación del estado directamente. Volvamos a los componentes y reutilizar los datos de la tienda. Para poder reutilizar datos reactivos de estado de la tienda, se deben utilizar propiedades computadas. Así que vamos a crear una propiedad de score() computada en el componente de la matriz:

En plantilla del componente padre, poner la expresión {{ score }}:

Y ahora, lo mismo para los componentes de dos niños.

Vuex es tan inteligente que hará todo el trabajo para poder reactivo actualizar la propiedad de score cada vez que cambia el estado. Intente cambiar el valor de score y ver cómo el resultado se actualiza en los tres componentes.

Crear Getters

Es, por supuesto, bueno que se puede reutilizarla. palabra clave de this.$store.state dentro de los componentes, como se vio anteriormente. Pero imagine las siguientes situaciones:

  1. En una aplicación a gran escala, donde varios componentes acceder el estado de la tienda mediante el uso de this.$store.state.score, decide cambiar el nombre de score. Esto significa que tienes que cambiar el nombre de la variable dentro de cada componente que lo utiliza!
  2. Desea usar un valor calculado del estado. Por ejemplo, supongamos que desea dar a los jugadores un bono de 10 puntos cuando el marcador llegue a 100 puntos. Por lo tanto, cuando la puntuación llega a 100 puntos, se agregan 10 puntos bonus. Esto significa que cada componente tiene que contener una función que reutiliza la puntuación y se incrementa en 10. Habrán repetido código en cada componente, que no es bueno!

Afortunadamente, Vuex ofrece una solución de trabajo para manejar tales situaciones. Imagina el comprador centralizado que tiene acceso a estado de la tienda y ofrece una función getter a cada uno de los elementos del estado. Si es necesario, este captador puede aplicar algún cálculo al elemento del estado. Y si usted necesita cambiar los nombres de algunas de las propiedades del estado, sólo los cambia en un solo lugar, en este getter.

Vamos a crear un captador de score():

Un captador recibe el state como su primer argumento y luego lo utiliza para obtener acceso a propiedades del estado.

Nota: Captadores reciben getters como segundo argumento. Se puede utilizar para acceder a los otros captadores en la tienda.

En todos los componentes, modificar la propiedad score() computada para utilizar el getter score() en lugar de puntuación del estado directamente.

Ahora, si decides cambiar la score a result, necesita actualizar solamente en un solo lugar: en el captador de score(). ¡Probar en este CodePen!

Crear Mutaciones

Las mutaciones son la manera permitida sólo para cambiar el estado. Desencadenar cambios simplemente significa cometer las mutaciones en los métodos de componentes.

Una mutación es prácticamente una función de controlador evento que se define por su nombre. Las funciones de controlador de mutación reciben un state como primer argumento. Se puede pasar un segundo argumento adicional, que se llama la payload para la mutación.

Vamos a crear una mutación de increment():

Las mutaciones no pueden ser llamadas directamente. Para realizar una mutación, se debe llamar al método commit() con el nombre de la mutación correspondiente y posibles parámetros adicionales. Podría ser sólo uno, como el paso en nuestro caso, o puede haber múltiples unos envuelven en un objeto.

Vamos a usar la mutación de increment() en los componentes de dos niño mediante la creación de un método denominado changeScore():

Estamos cometiendo una mutación en lugar de cambiar this.$store.state.score directamente, porque queremos explícitamente la pista el cambio realizado por la mutación. Así, hacemos nuestra lógica de aplicación más transparente, trazable y fácil a la razón sobre. Además, es posible implementar herramientas, como Vue DevTools o Vuetron, que pueden registrar todas las mutaciones, tomar instantáneas de estado y realizar viajes en el tiempo depuración.

Ahora, vamos a poner el método de changeScore() en uso. En cada plantilla de los componentes de dos niños, crear un botón y añadirle un oyente de evento click:

Al hacer clic en el botón, el estado se incrementa por 3, y este cambio se verá reflejado en todos los componentes. Ahora hemos logrado efectivamente comunicación Cruz-componente directa, que no es posible con el mecanismo de Vue.js incorporado "apoya abajo, eventos para arriba". Compruébelo en nuestro ejemplo CodePen.

Creación de Acciones

Una acción es sólo una función que compromete una mutación. Cambia el estado indirectamente, que permite la ejecución de las operaciones asincrónicas.

Vamos a crear una acción de incrementScore():

Acciones Obtén el contexto como primer parámetro, que contiene todos los métodos y propiedades de la tienda. Generalmente, sólo extraer las piezas que necesitamos utilizando ES2015 argumento desestructuración. El método commit es uno que necesitamos muy a menudo. Acciones también consigue un segundo argumento de la carga útil, al igual que las mutaciones.

En el componente de ChildB, modificar el método de changeScore():

Para llamar a una acción, usamos el método dispatch() con el nombre de la correspondiente acción y parámetros adicionales, así como con las mutaciones.

Ahora, el botón de Cambiar Score del componente ChildA incrementará el puntaje de 3. El botón idéntico desde el componente de ChildB hará lo mismo, pero después de un retardo de 3 segundos. En el primer caso, estamos ejecutando código síncrono y utilizamos una mutación, pero en el segundo caso estamos ejecutando código asíncrono y necesitamos usar en su lugar una acción. Vea cómo funciona en nuestro ejemplo CodePen.

Vuex Asignación de Ayudantes

Vuex ofrece algunos ayudantes útiles que pueden agilizar el proceso de creación de estado, captadores, mutaciones y acciones. En lugar de escribir manualmente las funciones, podemos decir Vuex para crear para nosotros. Vamos a ver cómo funciona.

En lugar de escribir la propiedad de score() computada como esta:

Sólo utilizamos el ayudante de mapState() como este:

Y la propiedad score() se crea automáticamente para nosotros.

Lo mismo vale para los captadores, mutaciones y acciones.

Para crear el captador score(), utilizamos el ayudante de mapGetters():

Para crear el método changeScore(), se utiliza el helper mapMutations() como este:

Cuando se utiliza para las mutaciones y acciones con el argumento de la carga útil, debemos pasar ese argumento en la plantilla donde definimos el controlador de eventos:

Si queremos changeScore() a utilizar una acción en lugar de una mutación, utilizamos mapActions() como este:

Una vez más, debemos definir el retraso en el controlador de eventos:

Nota: Todos los helpers de asignación devuelven un objeto. Así, si queremos usarlos en combinación con otros métodos o propiedades computadas locales, tenemos que combinar en un objeto. Afortunadamente, con el objeto de difundir operador (...), podemos hacerlo sin utilizar ninguna utilidad.

En nuestro CodePen, se puede ver un ejemplo de cómo todos los helpers de asignación se utilizan en la práctica.

Haciendo la Tienda Más Modular

Parece que el problema de complejidad constantemente obstaculice nuestro camino. Resolvimos antes mediante la creación de la tienda Vuex, donde nos facilita la gestión del estado y el componente comunicación. En esa tienda, lo tenemos todo en un solo lugar, fáciles de manipular y razonar acerca de.

Sin embargo, a medida que crece nuestra aplicación, este archivo de almacenamiento fácil de administrar se convierte en más grande y más grande y, consecuentemente, más difícil de mantener. Una vez más, necesitamos algunas estrategias y técnicas para mejorar la estructura de la aplicación, volviendo a su forma fácil de mantener. En esta sección, exploraremos varias técnicas que pueden ayudarnos en esta tarea.

Usando Módulos Vuex

Vuex nos permite dividir el objeto de almacén en módulos independientes. Cada módulo puede contener su propio estado, mutaciones, acciones, recibidores y otros módulos anidados. Después de que hemos creado los módulos necesarios, los registramos en la tienda.

Vamos a ver en acción:

En el ejemplo anterior, hemos creado dos módulos, uno para cada componente del niño. Los módulos son objetos simples como scoreBoard y resultBoard en el objeto de modules dentro de la tienda. El código de childA es el mismo que en la tienda de los ejemplos anteriores. En el código de childB, hemos añadido algunos cambios de nombres y valores.

Vamos a modificar ahora el componente ChildB para reflejar los cambios en el módulo resultBoard.

En el componente de ChildA, lo único que tenemos que modificar es el método de changeScore():

Como se puede ver, partiendo de la tienda en módulos hace mucho más ligero y fácil de mantener, mientras mantiene su gran funcionalidad. Si deseas el CodePen actualizado para verlo en acción.

Namespaced Módulos

Si quieren o necesitan utilizar el mismo nombre para una determinada propiedad o método en sus módulos, entonces usted debe considerar namespacing ellos. De lo contrario puede observar algunos extraños efectos secundarios, como ejecutar todas las acciones con los mismos nombres, obteniendo valores de estado incorrecto.

A un módulo de Vuex de nombres, sólo establece la propiedad namespaced a true.

En el ejemplo anterior, hemos hecho los nombres de propiedad y método de la misma para los dos módulos. Y ahora podemos utilizar una propiedad o un método marcado con el nombre del módulo. Por ejemplo, si queremos utilizar el getter score() desde el módulo resultBoard, tipo este: resultBoard/score. Si queremos que el captador de score() desde el módulo de scoreBoard, entonces escribe así: scoreBoard/score.

Ahora modifiquemos nuestros componentes para reflejar los cambios que hicimos.

Como se puede ver en nuestro ejemplo CodePen, ahora podemos utilizar el método o propiedad que desea y obtener el resultado que esperamos.

División de la Tienda de Vuex en Archivos Separados

En la sección anterior, hemos mejorado la estructura de la aplicación hasta cierto punto mediante la separación de la tienda en módulos. Hicimos la tienda limpia y más organizados, pero aún todo el código de la tienda y su mentira de módulos en el mismo archivo grande.

Así que el siguiente paso lógico es dividir la tienda Vuex en archivos separados. La idea es tener un archivo individual para la tienda de sí mismo y uno para cada uno de sus objetos, incluyendo los módulos. Esto significa tener archivos separados para el estado, getters, mutaciones, acciones y para cada módulo individual (store.js, state.js, getters.js, etcetera.) Se puede ver un ejemplo de esta estructura al final de la sección siguiente.

Utilizando Solo Componentes de Archivo Vue

Hemos hecho tan modular como podemos la tienda Vuex. Lo siguiente que podemos hacer es aplicar la misma estrategia a los componentes de Vue.js demasiado. Podemos poner cada componente en un archivo único, autónomo, con una extensión de .vue. Para saber cómo funciona, puede visitar la Página de Documentación de Componentes de Archivo Vue.

Así, en nuestro caso, tendremos tres archivos: Parent.vue, ChildA.vue y ChildB.vue.

Finalmente, Si combinamos los tres técnicas, terminaremos con la estructura siguiente o similar:

En nuestro tutorial repositorio de GitHub, puede ver el proyecto terminado con la estructura anterior.

Resumen

Resumamos algunos puntos principales que necesita para recordar acerca de Vuex:

Vuex es una biblioteca de gestión de estado que nos ayuda a construir aplicaciones complejas y a gran escala. Usa una tienda global y centralizada para todos los componentes en una aplicación. Para abstraer el estado, utilizamos captadores. Captadores son más o menos como computadas propiedades y son una solución ideal cuando queremos filtrar o calcular algo en tiempo de ejecución.

La tienda de Vuex es reactiva, y componentes directamente no pueden mutar de estado de la tienda. La única forma de mutar el estado está cometiendo las mutaciones, que son transacciones síncronas. Cada mutación debe realizar solamente una acción, debe ser tan simple como sea posible y sólo es responsable de actualizar una pieza del estado.

Lógica asincrónica debe ser encapsulado en acciones. Cada acción puede comprometer una o más mutaciones, y una mutación puede ser comprometida por más de una acción. Acciones pueden ser complejas, pero nunca cambian el estado directamente.

Por último, la modularidad es la clave del mantenimiento. Para ocuparse de complejidad y hacer nuestro código modular, utilizamos el principio de "divide y vencerás" y el código de división técnica.

Conclusión

¡Eso es todo! Ya sabes los conceptos principales detrás de Vuex, y estás listo para empezar a aplicar en la práctica.

Aras de la brevedad y sencillez, intencionalmente omití algunos detalles y características de Vuex, por lo que tendrás que leer la documentación de Vuex completa para conocer todo sobre Vuex y su conjunto.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.