Crea una cuenta y continúa aprendiendo 🚀

Regístrate o inicia sesión para continuar aprendiendo:

Frontend Aprendiz

Props y Events no son suficientes

Veamos cómo compartir estado entre componentes que están en distintas páginas, primero sin hacer uso de Pinia.

Definiendo un estado en el componente "app"

Tratemos entonces de definir un estado para nuestro componente app para tener una idea de cómo sería la implementación, si es que queremos mover nuestro estado hacia app y luego consumirlo desde los componentes que lo necesitan.

Nosotros agregaríamos un export default, como hemos venido haciendo para definir un estado y tendríamos aquí una variable details que es un arreglo.

Aquí nos resalta esto como error, porque este script está marcado como "setup", es decir, está usando composición API. Si queremos usar options API, quitamos ese término, y recordemos que "data" es un método que devuelve un objeto con el estado.

Pasando el estado a los componentes

De esta manera, si hacemos esto, luego nosotros podemos pasar una propiedad details con el valor de details de esta forma. Y esto estaría disponible para los componentes asociados a nuestras rutas.

Podríamos ir a CartView, y aquí, en CartView, podemos definir props.

Por ejemplo, podemos definir un llamado details y luego aquí podríamos mostrar el valor de ese details.

Nosotros podemos demostrar que esto funciona agregando algunos objetos, por ejemplo:

{
  "productId": 5,
  "quantity": 3
}

La idea es definir details en el nivel más alto, que es el componente de app, y luego pasar esto a través de props a nuestras páginas.

Por ejemplo, CartView ya declaró que va a recibir este prop. Si queremos tenerlo en HomeView, también lo tenemos que declarar.

Pero empecemos con CartView. En nuestro navegador, si nosotros nos dirigimos a cart, vemos que hay un producto agregado:

  • Producto con id: 5
  • Cantidad: 3

Esa información está fluyendo desde el componente principal app hacia CartView, y nosotros la estamos mostrando sobre nuestro componente cart.

Extensión a ProductList

Si queremos que los mismos detalles se muestren también en nuestro ProductList, entonces tenemos que primero recibir esos detalles en HomeView.

En HomeView, tendríamos algo similar a esto:

  1. Definir un prop llamado details.
  2. Pasarle details a ProductList.
  3. Declarar que ProductList va a recibir los detalles desde el exterior.

Entonces aquí enviamos details. Details, le pasamos como props a ProductList los detalles.

Ahora ProductList ya no tendría el estado internamente, sino que lo recibiría como details desde el exterior.

Para poder usar ProductList, tenemos que declarar una sección de component, y entonces ya podremos usar ProductList.

Guardamos y, como vemos, al ingresar a la página:

  • El componente app viene con details.
  • Esos details se envían a HomeView y se muestran en ProductList.
  • Esos mismos details se envían a CartView y se muestran en cart.

Gestión del estado con eventos

Es posible definir el estado en nuestro componente app y, a partir de allí, enviarlo a cada una de nuestras páginas.

Sin embargo, ¿qué pasa si queremos que el botón "Agregar al carrito" (v-btn) siga funcionando?

No es tan sencillo, porque como el estado se encuentra en nuestro componente app, este botón va a emitir primero un evento.

  • Evento emitido por ProductList: ProductList tendrá que emitir nuevamente un evento para que lo reciba HomeView.
  • Evento emitido por HomeView: HomeView tendrá que emitir un evento para que lo reciba app.

Es decir, la gestión del estado comienza a complicarse.

El uso de props y el uso de eventos es importante porque nos permite entender cómo funciona la comunicación entre componentes.

Gestión de estado global con stores

Cuando tenemos páginas y usamos v-router, lo usual será tener una gestión de estados global.

Por ejemplo, este componente app tiene un estado. Ese estado lo estamos pasando a RouterView, y de esta manera:

  • HomeView lo recibe y lo envía nuevamente a ProductList.
  • ProductList lo envía a cart.

Cuando cambiamos de página y nos dirigimos al carrito de compras:

  1. App.vue define el estado.
  2. RouterView le pasa esta información a CartView.
  3. CartView lo muestra en cart.

Si queremos agregar un producto al carrito:

  1. Evento de click en v-btn dentro de productCard.
  2. v-btn emite el evento addProduct.
  3. ProductList reconoce el evento pero no puede modificar el estado.
  4. ProductList emite el evento a HomeView.
  5. HomeView detecta el evento y lo reenvía a app.
  6. app finalmente modifica details para agregar el producto.

Como vemos, hay situaciones en las que el uso de eventos y props comienzan a complicarse, sobre todo cuando tenemos muchos componentes ubicados a distintos niveles del proyecto.

En estos casos, se recomienda el uso de stores.

Esta lección no cuenta con recursos adicionales.

Si crees que hace falta algo, o necesitas ayuda, puedes publicar una pregunta en el foro.

Tratemos entonces de definir un estado para nuestro componente "app" para tener una idea de cómo sería la implementación, si es que queremos mover nuestro estado hacia "app" y luego consumirlo desde los componentes que lo necesitan. Nosotros agregaríamos un export default, como hemos venido haciendo para definir un estado y y tendríamos aquí una variable “details” que es un arreglo. Aquí nos resalta esto como error, porque este script está marcado como "setup", es decir, está usando composición API. Si queremos usar options API, quitamos ese término, y recordemos que "data" es un método que devuelve un objeto con el estado. De esta manera, si hacemos esto, luego nosotros podemos pasar una propiedad "details" con el valor de "details" de esta forma. Y esto estaría disponible para los componentes asociados a nuestras rutas. O sea que, podríamos ir a "CartView", y aquí, en “CartView”, podemos definir props. Por ejemplo, podemos definir un llamado "details" y luego aquí podríamos mostrar el valor de ese "details". Nosotros podemos demostrar que esto funciona agregando por aquí algunos objetos, por ejemplo, vamos a poner "productId 5, quantity: 3" La idea es definir "details" en el nivel más alto, que es el componente de "app", y luego pasar esto a través de props a nuestras páginas. Por ejemplo, "CartView" ya declaró que va a recibir este prop, si queremos tenerlo en “HomeView” también lo tenemos que declarar. Pero empecemos con "CartView". En nuestro navegador, si nosotros nos dirigimos a "cart", vemos que hay un producto agregado, el producto con “id 5” y “cantidad: 3”, esa información está fluyendo desde el componente principal up hacia "CartView" y nosotros le estamos mostrando sobre nuestro componente "cart". Si queremos que los mismos detalles se muestren también en nuestro "ProductList", entonces tenemos que primero recibir esos detalles en "HomeView". Entonces, en "HomeView", tendríamos algo similar a esto. En "HomeView", tendríamos también un prop llamado "details" y luego habría que pasarle "details" a "ProductList" para que “ProductList” lo pueda recibir. Tenemos que declarar que "ProductList" va a recibir los detalles desde el exterior. Entonces aquí enviamos "details". "Details", le pasamos como props a “ProductList” los detalles. Entonces aquí ya no estaría, sino que ahora sería unos props, lo recibiría como "details". Entonces yo no estaría aquí. Y con esto lo que conseguimos es Para poder usar el "ProductList" tenemos que declarar aquí una sección de “component”. Y entonces aquí ya podremos usar “ProductList”. Guardamos, y como vemos, al ingresar a la página, nuestro componente "app" y viene con "details", esos "details" se envian a “homeView” y se muestran aquí en “ProductList”. Esos mismos "details" se envían a "CartView" y se muestran aquí en este "cart". O sea, es posible continuar gestionando el estado de la misma manera. Es posible definir el estado en nuestro componente "app" y a partir de allí enviarlo a cada una de nuestras páginas. Sin embargo, ¿Qué pasa si nosotros queremos que este "v-btn" de “agregar al carrito” siga funcionando? No es tan sencillo, porque como el estado se encuentra en nuestro componente "app", este botón va a emitir primero un evento. El evento va a ser recibido por “ProductList”. “ProductList” va a tener que emitir nuevamente un evento para que lo reciba "HomeView" y finalmente "HomeView" va a tener que emitir un evento para que lo reciba "app". Es decir, la gestión del estado comienza a complicarse el uso de props y el uso de eventos es importante porque nosotros tenemos que saber cómo funciona la comunicación entre componentes. Hay componentes que van a estar muy asociados a otros. Sin embargo, cuando tenemos páginas y hacemos uso de “v-router”, lo usual será tener una gestión de estados global. Por ejemplo, este componente “app” tiene un estado. El estado lo estamos pasando a este “RouterView” y de esta manera "HomeView" lo recibe y lo envía nuevamente a “ProductList”, y “ProductList” a su vez lo envía a "cart". Cuando cambiamos de página y nos dirigimos a la página del carrito de compras de la misma manera “App.vue” define el estado “RouterView” le pasa esta información al “CartView” y este “CartView” lo muestra aquí en este componente “cart”. Si nosotros queremos agregar un producto al carrito. El evento de click ocurre en este “v-btn” a nivel de “productCard”. Este "v-btn" emitirá un evento “addProduct”. Ese evento será reconocido por “ProductList”, sin embargo, ahora ya no se puede agregar el producto al carrito directamente porque el estado ya no está en “ProductList”. Habría que emitir un evento y recibir luego ese evento en "HomeView" para posteriormente, luego de detectar el evento, volver a emitir otro evento y se detecta aquí en "app". Y aquí en “app” podríamos finalmente modificar los detalles para agregar un producto más. Como vemos, hay situaciones en las que el uso de eventos y props comienzan a complicarse, sobre todo cuando tenemos muchos componentes que están ubicados a distintos niveles de nuestro proyecto. En estos casos es cuando se recomienda el uso de “stores”.

¿Tienes dudas?

Publicar pregunta

¡Comparte conocimiento!

X

Volver al índice

Regístrate

Inicia sesión para llevar un control de tu progreso.

Capítulos


























































58

Props y Events no son suficientes


































































Espera un momento 🎁 ...

¿Te gustaría aprender a programar, gratis?

Mago de Programación y más

Sólo debes registrarte 😉.