El libro "Vue.js en acción"

imagen Hola habrozhiteli! El propósito de este libro es brindarle el conocimiento con el que no dudará en unirse a cualquier proyecto que use esta biblioteca. El libro está dirigido a todos los que estén interesados ​​en aprender Vue.js y tengan experiencia con JavaScript, HTML y CSS. No es necesario que tenga un conocimiento profundo de esta área, pero comprender los conceptos básicos, como matrices, variables, bucles y elementos HTML, no le hará daño.

Debajo del corte hay un pasaje en forma del capítulo de Vuex, que describe: cuál es la condición; el uso de captadores; implementación de mutaciones; agregando acciones; trabajar con métodos de ayuda de Vuex; módulos y configuración de proyectos.

10.1 ¿Por qué necesitamos Vuex?


La biblioteca Vuex gestiona el estado. Lo almacena centralmente, lo que facilita el acceso a cualquier componente. El estado es información o datos que admiten la aplicación. Esto es importante porque necesitamos un mecanismo confiable y comprensible para trabajar con esta información.

Si ya tiene experiencia trabajando con otros marcos para crear aplicaciones de una sola página, algunos de estos conceptos pueden parecerle familiares. Por ejemplo, React usa un sistema de administración de estado similar llamado Redux. Vuex y Redux están influenciados por el proyecto Flux. Esta es la arquitectura propuesta por Facebook, que está diseñada para simplificar la construcción de aplicaciones web de clientes. Contribuye al movimiento de datos en una dirección: desde acciones hasta el despachador, luego al almacenamiento y al final a la vista. Este enfoque le permite separar el estado del resto de la aplicación y fomenta las actualizaciones sincrónicas. Puede obtener más información sobre Flux en la documentación oficial en facebook.imtqy.com/flux/docs/overview.html.

Vuex funciona con el mismo principio, ayudando a cambiar el estado de forma predecible y sincrónica. Los desarrolladores no necesitan preocuparse por las consecuencias de actualizar el estado con funciones síncronas y asíncronas. Imagine que estamos interactuando con una API de servidor que devuelve datos en formato JSON. ¿Qué sucede si al mismo tiempo estos datos son modificados por una biblioteca de terceros? No queremos un resultado impredecible. Vuex ayuda a evitar tales situaciones al eliminar cualquier cambio asincrónico.
Probablemente se esté preguntando por qué incluso necesitamos la biblioteca Vuex. Al final, Vue.js le permite pasar información a los componentes. Como sabe en capítulos anteriores, los parámetros de entrada y los eventos de usuario están destinados a esto. Incluso podríamos crear nuestro propio bus de eventos para la transferencia de datos y la comunicación entre componentes. Un ejemplo de tal mecanismo se presenta en la Fig. 10.1

Esto sería apropiado para aplicaciones pequeñas con un puñado de componentes. En este caso, solo necesita transferir información a unos pocos destinatarios. Pero, ¿qué pasa si la aplicación es más grande, más compleja y en capas? Está claro que en un proyecto grande no es tan fácil hacer un seguimiento de todas las funciones de devolución de llamada, parámetros de entrada y eventos.

Solo para tales situaciones, se creó la biblioteca Vuex. Le permite organizar el trabajo con el estado en forma de un repositorio centralizado. Imagine un escenario que vale la pena pensar en usar Vuex. Por ejemplo, estamos trabajando en un blog con artículos y comentarios que puede crear, editar y eliminar. Al mismo tiempo, tenemos un panel de administración que le permite bloquear y agregar usuarios.

Veamos cómo se implementa esto usando Vuex. En la fig. La figura 10.2 muestra que el componente EditBio es un elemento secundario del panel de administración. Necesita acceso a la información del usuario para poder actualizarla. Al trabajar con Vuex, podemos acceder al repositorio central, modificar los datos y guardar los cambios directamente desde el componente EditBio. Esto es mucho mejor que pasar información desde la instancia raíz de Vue.js al componente Admin y luego a EditBio usando los parámetros de entrada. Sería difícil para nosotros hacer un seguimiento de los datos ubicados en diferentes lugares.

imagen

imagen

Sin embargo, el uso de Vuex tiene un precio en forma de código adicional y complejidad de la estructura de la aplicación. Como ya se mencionó, es mejor no utilizar esta biblioteca en proyectos simples que constan de varios componentes. Su potencial real se manifiesta en grandes aplicaciones con un estado más complejo.

10.2 Estado y mutación en Vuex


Vuex almacena el estado de toda la aplicación en un solo objeto, que también se llama una única fuente de verdad. Como su nombre indica, todos los datos se recopilan en un lugar y no se duplican en otras partes del código.
SUGERENCIA

Vale la pena señalar que no estamos obligados a almacenar todos nuestros datos en Vuex. Los componentes individuales pueden tener su propio estado local. En ciertas situaciones, esto es preferible. Por ejemplo, su componente tiene una variable que se usa solo dentro de él. Ella debe permanecer local.
Considere un ejemplo simple de trabajar con estado en Vuex. Todo nuestro código se colocará en un archivo. Más adelante aprenderá cómo agregar Vuex a un proyecto usando Vue-CLI. Abra un editor de texto y cree el archivo vuex-state.html. Mostraremos un mensaje ubicado en el repositorio central y un contador. El resultado se muestra en la fig. 10.3

imagen Primero, agregue etiquetas de script con enlaces a Vue y Vuex. Luego cree el marcado HTML. Utilizaremos las etiquetas H1, H2, H3 y botón. La etiqueta h1 muestra el encabezado con una variable local declarada en la instancia de Vue.js. Los mensajes de bienvenida y de contador se ejecutan como propiedades calculadas basadas en el repositorio de Vuex.

El elemento del botón desencadena una acción de incremento. Copie el código del Listado 10.1 en el archivo vuex-state.html.

imagen

Cuando haya terminado con el marcado HTML, comencemos a crear el repositorio de Vuex. Contendrá todos los datos de la aplicación, incluidas las propiedades msg y count.

Para actualizar el estado, usamos mutaciones. Esto es algo así como setters de otros lenguajes de programación. El configurador establece el valor, la mutación actualiza el estado del programa. En Vuex, las mutaciones deben ser sincrónicas. En nuestro ejemplo, el contador se incrementa solo con el clic de un botón, por lo que no hay necesidad de preocuparse por el código asincrónico (más adelante consideraremos acciones que ayuden a resolver problemas con la asincronía).

Cree una función de incremento dentro del objeto de mutaciones que incremente el estado. Tome el código en el Listado 10.2 y péguelo en la parte inferior del archivo vuex-state.html.

imagen

Por lo tanto, hemos preparado el marcado HTML y el repositorio Vuex. Ahora puede agregar lógica que los conectará. Queremos que la plantilla muestre los valores de mensaje y contador, que son parte del estado de Vuex. Además, el contador debe actualizarse.

Cree una instancia de Vue.js con una nueva función de datos que devolverá una propiedad de encabezado local con el texto de la aplicación Vuex. En la sección calculada, agregue las propiedades calculadas de bienvenida y contador. El primero devolverá store.state.msg y el segundo - store.state.count.

Finalmente, necesita agregar un método llamado incremento. Se ha declarado una mutación en el repositorio de Vuex, pero no podemos usarla directamente para actualizar el estado. Se proporciona una función de confirmación especial para esto. Le dice a Vuex que actualice el repositorio y, por lo tanto, guarda los cambios. La expresión store.commit ('incremento') realiza la mutación. Inserte el siguiente fragmento (Listado 10.3) inmediatamente después del código creado en el Listado 10.2.

imagen

¡Esta es una aplicación de trabajo completa basada en Vuex! Intente presionar el botón; cada vez que presione el contador debería aumentar en 1.

Actualice el código para que al presionar el botón se incremente el contador en 10. Si observa de cerca la mutación de incremento, notará que solo se necesita un argumento, estado. Pasemos otro, llamémoslo carga útil. Se pasará por el método de incremento, que se crea en la instancia raíz de Vue.js.

Copie el contenido de vuex-state.html en el nuevo archivo vuex-state-pass.html. Usando esta aplicación como ejemplo, mostramos cómo se pasan los argumentos.

Como puede ver en el Listado 10.4, solo el objeto de mutaciones y el método de incremento deben actualizarse. Agregue al incremento de mutación otro argumento llamado carga útil. Este es el valor por el cual aumentará state.count. Busque la llamada a store.commit dentro del método de incremento y especifique 10 como segundo argumento. Actualice el archivo vuex-state.html como se muestra a continuación.

imagen

Guarde el archivo vuex-state-pass.html y ábralo en un navegador. Ahora, cuando se presiona el botón, el contador debería aumentar en 10, y no en 1. Si algo salió mal, verifique la consola del navegador y asegúrese de que no haya errores tipográficos.

10.3 Captadores y acciones


En el ejemplo anterior, accedimos a la tienda directamente desde las propiedades calculadas. Pero, ¿y si tuviéramos varios componentes que necesitaran el mismo acceso? Supongamos que queremos mostrar un mensaje de bienvenida en mayúsculas. En este caso, los captadores nos ayudarán.

Getters son parte de Vuex. Le permiten implementar el acceso unificado al estado en todos los componentes. Tomemos un ejemplo de la sección 10.2 y en lugar de acceso directo al almacenamiento a través de propiedades calculadas, usamos getters. Además, hacemos que el captador de la propiedad msg traduzca todas sus letras a mayúsculas.

Copie el contenido del archivo vuex-state-pass.html en vuex-state-getter-action.html. Para simplificar la tarea, deje el código HTML sin cambios. Al final, deberías obtener algo similar a la fig. 10.4

imagen Como puede ver, el mensaje de Hello World ahora se muestra en palabras. Al presionar el botón Press Me, el contador se incrementa de la misma manera que en el ejemplo anterior.

Localice la construcción Vuex.Store dentro del nuevo archivo vuex-state-getter-action.html inmediatamente debajo de la etiqueta imagen Agregue un nuevo objeto después de mutaciones llamadas getters. Cree los métodos msg y count dentro de este objeto, como se muestra en el Listado 10.5. Ambos métodos aceptan el mismo argumento de estado.

El captador msg devolverá state.msg.toUppercase (). Gracias a esto, el mensaje siempre se muestra en mayúsculas. En get getter, devolveremos state.count. Después de agregar getters debajo de las mutaciones, el archivo vuex-state-getter-action.html debería verse así.

imagen

Las acciones son otra parte integral de Vuex. Mencioné anteriormente que las mutaciones deben ser sincrónicas. Pero, ¿qué pasa si trabajamos con código asincrónico? ¿Cómo hacer llamadas asíncronas capaces de cambiar de estado? Las acciones de Vuex nos ayudarán con esto.
Imagine que la aplicación está accediendo al servidor y esperando una respuesta. Este es un ejemplo de una acción asincrónica. Desafortunadamente, las mutaciones son asíncronas, por lo que no podemos usarlas aquí. En su lugar, agregue una operación asincrónica basada en la acción Vuex.

Para crear un retraso, use la función setTimeout. Abra el archivo vuex-state-getter-action.html y agregue el objeto de acciones inmediatamente después de los captadores. Dentro de este objeto, coloque la acción de incremento, que toma los argumentos de contexto y carga útil. Usando el contexto, guardaremos los cambios. Coloque la operación context.commit dentro de setTimeout. De esta forma simulamos un retraso en el servidor. También podemos pasar el argumento de la carga útil a context.commit, que luego entra en la mutación. Actualice el código basado en el Listado 10.6.

Después de actualizar Vuex.Store, puede proceder a la instancia raíz de Vue.js. La propiedad calculada no accederá a la tienda directamente, como antes, sino a través de getters. También estamos modificando el método de incremento. Para acceder a la nueva propiedad Vuex que creamos anteriormente, utilizará la llamada store.dispatch ('incremento', 10).

imagen

El primer argumento para la llamada de despacho es el nombre de la acción, y el segundo argumento siempre contiene datos adicionales que se pasan a esta acción.
CONSEJO

Los datos adicionales pueden ser una variable regular o incluso un objeto.
Actualice la instancia de Vue.js en el archivo vuex-state-getter-action.html como se muestra en el Listado 10.7.
imagen

Descargue la aplicación y presione el botón varias veces. Debería notar un retraso, pero el contador aumentará en 10 después de cada presión.

10.4 Usando Vuex en un proyecto de tienda de mascotas usando Vue-CLI


Volvamos al proyecto de la tienda de mascotas en el que estábamos trabajando. Si no lo ha olvidado, decidimos agregar animaciones y transiciones. Ahora integramos la biblioteca Vuex que conocimos anteriormente.

Transferimos los datos de las mercancías al almacén. Como recordará de los capítulos anteriores, los datos se inicializaron en el enlace creado dentro del componente Principal. Ahora este enlace debería generar un nuevo evento que inicialice el repositorio de Vuex. También agregaremos los productos de propiedad calculados, que recupera productos utilizando el captador (lo crearemos más adelante). El resultado final se verá como en la Fig. 10.5

imagen

10.4.1. Instale Vuex con Vue-CLI


Primero, instale Vuex! Este es un proceso simple. Prepare la última versión de la tienda de mascotas en la que trabajamos en el capítulo 8. También puede descargar todo el código para este capítulo en GitHub en github.com/ErikCH/VuejsInActionCode.

Abra una ventana de terminal y vaya al directorio raíz del proyecto. Para instalar la última versión de Vuex, ejecute el siguiente comando:

$ npm install vuex 

y guarde el registro al respecto en el archivo package.json de la tienda de mascotas.

Ahora debe agregar el almacenamiento al archivo main.js, que se encuentra en la carpeta src. El repositorio en sí aún no existe, pero lo importamos de todos modos. Por lo general, está en el archivo src / store / store.js, pero puede elegir una ruta diferente: todos los desarrolladores tienen sus propias preferencias. Detengámonos en la opción generalmente aceptada. Más adelante en este capítulo discutiremos una estructura de directorio alternativa usando módulos.

Debe agregar almacenamiento a la instancia raíz de Vue.js debajo del enrutador, como se muestra en el Listado 10.8. Por cierto, utilizamos el estándar ES6, por lo que store: store se puede acortar para almacenar.

imagen

Después de conectar el almacenamiento a la instancia raíz, podemos acceder a él desde cualquier parte de la aplicación. Cree el archivo src / store / store.js. En él colocaremos el repositorio de Vuex con información sobre los productos que ofrece la tienda de mascotas. En la parte superior, agregue dos declaraciones de importación, una para Vue y Vuex. Luego especifique Vue.use (Vuex) para poner todo junto.

Importamos el repositorio en el archivo main.js desde ./store/store. Ahora necesita exportar el objeto de la tienda dentro de store.js. Como puede ver en el Listado 10.9, exportamos un valor de tienda constante igual a Vuex.Store.

Primero, agregue objetos con estado y mutaciones. El estado contendrá un objeto vacío llamado productos. Pronto lo llenaremos con el método initStore. La mutación se llama SET_STORE, asignará los bienes transferidos a la propiedad state.products. Pegue el código de la siguiente lista en el archivo src / store / store.js que acabamos de crear.

imagen

Necesitamos crear una acción y captador en el repositorio. Un getter devolverá un objeto de productos. La acción es un poco más complicada. Debe transferir el enlace creado, que lee el archivo static / products.json usando Axios, al objeto de acciones dentro de Vuex.

Mencioné anteriormente que las mutaciones deben ser sincrónicas y que solo las acciones dentro de Vuex pueden aceptar código asincrónico. Para evitar esta limitación, coloque el código Axios en la acción Vuex.

Cree un objeto de acciones en el archivo store.js y agregue el método initStore. Copie el contenido del enlace creado del componente / archivo Main.vue en este método. En lugar de asignar respuesta.datos.productos al objeto de productos, invocamos la mutación utilizando la función de confirmación. Pase response.data.products como argumento a SET_STORE. El código resultante debería tener este aspecto (Listado 10.10).

imagen

Ya casi hemos terminado, solo tenemos que actualizar el archivo Main.vue y transferir los productos del objeto de productos locales al repositorio de Vuex. Abra el archivo src / components / Main.vue y busque la función de datos. Elimine la línea de productos: {}. Accederemos a los productos desde la propiedad calculada que devuelve la tienda.

Encuentre las propiedades calculadas cartItemCount y sortedProducts dentro de Main.vue, deben ir justo después de la sección de métodos. Agregue la propiedad de productos y haga que devuelva el captador del mismo nombre.

Conectamos el repositorio a la instancia raíz de Vue.js en el archivo main.js, por lo que ya no necesitamos importarlo. Además, cuando se utiliza Vue-CLI, el almacenamiento siempre está disponible en forma de esto. $ Store. No olvide el signo $, de lo contrario, se producirá un error. Agregue la propiedad de productos calculados, como se muestra en el Listado 10.11.

imagen

Busque el enlace creado en el que se inicializa el objeto de productos y elimine su contenido. En su lugar, inserte la llamada de acción initStore que creamos anteriormente en el repositorio de Vuex. Para llamar a una acción, use la función de despacho, como en el ejemplo anterior. El listado 10.12 muestra cómo debería verse el enlace creado después de actualizar el archivo Main.vue.

imagen

Eso debería ser suficiente. Ejecute el comando npm run dev en la terminal y aparecerá una ventana con la aplicación de la tienda de mascotas en la pantalla. Intente poner los productos en la canasta y asegúrese de que todo funcione como debería. Si algo salió mal, busque errores en la consola. En el archivo src / store / store.js, en lugar de Vuex.store, puede escribir accidentalmente Vuex.Store. Recuerda esto!

10.5 Métodos de ayuda Vuex


Vuex proporciona métodos auxiliares convenientes que hacen que el código sea más conciso y eliminan la adición de los mismos captadores, establecedores, mutaciones y acciones. Para obtener una lista completa de los métodos de ayuda de Vuex, consulte la guía oficial en vuex.vuejs.org/guide/core-concepts.html. Veamos cómo funcionan.

El método de ayuda principal que debe conocer se llama mapGetters. Se utiliza para agregar todos los captadores disponibles a la sección calculada y no requiere enumerar cada uno de ellos. Pero antes de usarlo, debe importarlo dentro del componente. Una vez más, regrese a la tienda de mascotas y agregue el método mapGetters.

Abra el archivo src / components / Main.vue y busque la etiqueta del script. En algún lugar dentro de esta etiqueta, se debe importar el componente Encabezado. Conecte mapGetters inmediatamente después de esta importación, como se muestra en el Listado 10.13.

imagen

Ahora necesita actualizar la propiedad calculada. Encuentre la función de productos en la sección calculada e inserte el objeto mapGetters en su lugar.

mapGetters es un objeto único, para su correcto funcionamiento es necesario utilizar el operador de propagación de ES6; expande la expresión en una situación en la que se esperan argumentos (cero o más). Puede leer más sobre esta sintaxis en la documentación de MDN en developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_syntax .

mapGetters se asegurará de que todos los captadores se agreguen como propiedades calculadas. Esta es una forma mucho más simple y elegante que escribir una propiedad computada separada para cada captador. Todos los captadores se enumeran en la matriz mapGetters. Agregue este método auxiliar al archivo Main.vue (Listado 10.14).

imagen

Después de ejecutar el comando npm run dev, la tienda de mascotas debería funcionar como antes. El método de ayuda mapGetters no parece muy útil hasta ahora, pero cuantos más captadores agreguemos, más tiempo ahorrará.

Hay tres métodos auxiliares más que debe conocer: mapState, mapMutations y mapActions. Todos funcionan de manera similar, reduciendo la cantidad de código repetitivo que debe escribir manualmente.

Imagine que su repositorio contiene varios datos y el acceso al estado se realiza directamente desde el componente, sin utilizar ningún captador. En este caso, puede usar el método mapState dentro de la sección calculada (Listado 10.15).

imagen

Ahora imagine que necesita usar varias mutaciones en un componente. Para simplificar este proceso, use el método auxiliar mapMutations (Listado 10.16), como se hace con mapState y mapGetters. Siguiente mut1 vincula this.mut1 () a esto. $ Store.commit ('mut1').

imagen

Finalmente, considere el método auxiliar mapActions. Le permite agregar acciones Vuex a la aplicación, eliminando la necesidad de crear métodos con llamadas de despacho en cada caso. Volviendo al ejemplo anterior, imagine que la aplicación contiene algunas operaciones asincrónicas. Dado que se excluye el uso de mutaciones, debemos recurrir a la acción. Después de crearlos en Vuex, debe acceder a ellos en el objeto de métodos del componente. Este problema se puede resolver usando mapActions. act1 vinculará this.act1 () a esto. $ store.dispatch ('act1'), como se muestra en el Listado 10.17.

imagen

Finalmente, considere el método auxiliar mapActions. Le permite agregar acciones Vuex a la aplicación, eliminando la necesidad de crear métodos con llamadas de despacho en cada caso. Volviendo al ejemplo anterior, imagine que la aplicación contiene algunas operaciones asincrónicas. Dado que se excluye el uso de mutaciones, debemos recurrir a la acción. Después de crearlos en Vuex, debe acceder a ellos en el objeto de métodos del componente. Este problema se puede resolver usando mapActions. act1 vinculará this.act1 () a esto. $ store.dispatch ('act1'), como se muestra en el Listado 10.17.

imagen

A medida que la aplicación crezca, estos métodos auxiliares serán cada vez más útiles, reduciendo la cantidad de código que debe escribirse. Tenga en cuenta que debe pensar en los nombres de propiedad en su repositorio, ya que los métodos auxiliares le permiten acceder a ellos en componentes.

10.6 Breve introducción a los módulos


Al comienzo de este capítulo, creamos el archivo store.js en el directorio src / store. Para un proyecto pequeño, este enfoque es bastante apropiado. Pero, ¿qué pasa si estamos tratando con una aplicación mucho más grande? El archivo store.js crecerá rápidamente y será difícil hacer un seguimiento de todo lo que sucede en él.
Para resolver este problema, Vuex ofrece el concepto de módulos. Los módulos le permiten dividir el almacenamiento en varias partes más pequeñas. Cada módulo tiene sus propios estados, mutaciones, acciones y captadores, incluso puede anidarlos entre sí.

Reescribimos la tienda de mascotas usando módulos. El archivo store.js permanecerá en su lugar, pero al lado debe crear la carpeta de módulos y colocar el archivo products.js allí. La estructura del directorio debe verse como la de la fig. 10.6

imagen Dentro de products.js, debe crear cuatro objetos: estado, captadores, acciones y mutaciones. El contenido de cada uno de ellos debe copiarse del archivo store.js.

Abra el archivo src / store / store.js y comience a copiar el código de él. Cuando termine, el archivo products.js debería verse así (Listado 10.18).

Ahora necesitamos exportar todo el código que agregamos al archivo product.js. Esto lo importará a store.js. En la parte inferior del archivo, agregue la expresión exportación predeterminada. Esta es una instrucción de exportación en formato ES6 que le permite importar este código desde otros archivos (Listado 10.19).

El archivo store.js debe actualizarse. Agregue un objeto de módulos, dentro del cual puede enumerar todos los módulos nuevos. Recuerde importar el archivo de módulos / productos que creamos anteriormente.

imagen

Nuestro ejemplo contiene solo un módulo, así que agréguelo inmediatamente al objeto de módulos. También debe eliminar todo lo innecesario de Vuex.Store, como se muestra en el Listado 10.20.

imagen

Al importar los módulos, completamos el proceso de refactorización. Después de actualizar la página, la aplicación debería funcionar exactamente como antes.
Espacios de nombres en Vuex

En algunos proyectos grandes, la modularización puede causar ciertos problemas. A medida que se agregan nuevos módulos, pueden surgir conflictos con los nombres de acciones, captadores, mutaciones y propiedades de estado. Por ejemplo, puede asignar accidentalmente el mismo nombre a dos captadores en diferentes archivos. Y, dado que todo está en un espacio de nombres global global en Vuex, se producirá un error de clave duplicada en la consola.
Para evitar este problema, coloque cada módulo en un espacio de nombres separado. Para hacer esto, solo especifique namespaced: true en la parte superior de Vuex.store. Lea más sobre esta característica en la documentación oficial de Vuex en vuex.vuejs.org/en/guide/modules.html.
»Se puede encontrar más información sobre el libro en el sitio web del editor
» Contenidos
» Extracto

Cupón de 25% de descuento para vendedores ambulantes - Vue.js

Tras el pago de la versión en papel del libro, se envía una versión electrónica del libro por correo electrónico.

Source: https://habr.com/ru/post/448304/


All Articles