Crea una cuenta y continúa aprendiendo 🚀

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

Frontend Aprendiz

Refactor: ShoppingCartItem

Continuemos organizando nuestro proyecto, creando un componente nuevo para representar a cada item de nuestro carrito de compras. Mostremos además una imagen circular por cada producto agregado.

Agregando imágenes a la vista del carrito de compras

Ya estamos mostrando una imagen para cada producto en nuestra vista de home, sin embargo, nos falta hacerlo en nuestra vista cart, porque aquí todavía no tenemos la imagen de los productos.

Modificación del componente ShoppingCart

Para agregar la imagen en el cart, tenemos que modificar nuestro componente ShoppingCart.

Actualmente, ShoppingCart es responsable de:

  • Mostrar una lista de items.
  • Definir un card.
  • Mostrar un título y un texto en caso de que no haya items agregados.

Lo primero que podemos hacer antes de agregar una imagen es desplazar este list-item a un componente separado para organizar mejor nuestro código.

Creación del componente ShoppingCartItem

ShoppingCart será un card con un título y un texto. Sin embargo, cada item será un componente distinto. Para ello:

  1. Dentro de la carpeta components, agregamos un nuevo componente llamado ShoppingCartItem.vue.
  2. Este componente permitirá tener un mayor control sobre la vista de cada item agregado al carrito de compras.
  3. En el código, reemplazamos v-list-item con ShoppingCartItem.
  4. ShoppingCartItem tendrá asignado el v-for y el key, generando un ShoppingCartItem por cada detalle.

Definiendo el template de ShoppingCartItem

Para que esto funcione:

  • ShoppingCartItem tendrá un template conformado por un v-list-item.
  • Debemos importarlo en ShoppingCart.
  • Lo definimos dentro de components.
  • Luego, lo usamos con la sintaxis apropiada.
  • Se recomienda escribirlo en mayúsculas para diferenciarlo de los componentes de Vuetify.

Uso de props y TypeScript

Ahora que cada item tiene su propio componente, es más fácil gestionarlo. Para esto:

  1. Definimos una sección script con TypeScript.
  2. Hacemos que ShoppingCartItem reciba un prop llamado detail.
  3. Al usar Options API, definimos un objeto con export default y agregamos props.
  4. Importamos PropType y definimos el tipo CardDetail, estableciendo required: true.

Manejo de eventos de clic

Dado que el item ahora tiene su propio componente:

  • Los eventos de clic deben llamar métodos desde ShoppingCartItem.
  • Movemos la sección de métodos de ShoppingCart a ShoppingCartItem.
  • Importamos mapActions desde Pinia.
  • Importamos nuestro store.
  • Nos aseguramos de que ShoppingCartItem reciba correctamente la propiedad detail.
  • Pasamos la propiedad detail con detail: detail.
  • Iteramos en ShoppingCart, pero cada ShoppingCartItem recibe un solo detalle a la vez.

Agregando la imagen del producto

Para agregar la imagen dentro de ShoppingCartItem:

  1. Usamos la etiqueta v-img.
  2. Definimos el atributo source con la URL de la imagen del producto.
  3. Creamos una Computed Property basada en la propiedad detail.
  4. Retornamos this.detail.product.image, y si no hay imagen, asignamos una por defecto.

Ajuste de tamaño y forma de la imagen

Después de agregar la imagen, notamos que ocupa demasiado espacio. Para solucionar esto:

  • Limitamos la altura de v-img a 40 píxeles.
  • Encerramos la imagen dentro de un v-avatar para hacerla circular.
  • Usamos la propiedad size en v-avatar para definir su tamaño, evitando aplicar estilos directamente sobre v-img.

Así, logramos agregar correctamente la imagen de cada producto en el carrito de compras, asegurando una mejor organización del código y una correcta visualización de los elementos.

Esta lección no cuenta con recursos adicionales.

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

Ya estamos mostrando una imagen para cada producto en nuestra vista de home, sin embargo nos falta hacer ello en nuestra vista cart, porque aquí todavía no tenemos la imagen de los productos. Para agregar allí la imagen tenemos que modificar nuestro componente shopping cart. Actualmente shopping cart es responsable de mostrar una lista de items, pero así mismo es responsable de definir un card, un título y un texto en caso que no hayan items agregados. Lo primero que podemos hacer antes de agregar una imagen es desplazar este list-item a un componente para organizar mejor nuestro código. ShoppingCart entonces será un card con un título y un texto, sin embargo cada item será un componente distinto. O sea que dentro de la carpeta de components vamos a agregar un componente más que se va a llamar ShoppingCartItem. Este componente ShoppingCartItem.vue nos va a permitir tener un mayor control sobre la vista que representa a cada item que ha sido agregado al carrito de compras. Entonces aquí nuestro código cambiaría. Ya no vamos a tener un v-list-item, vamos a tener más bien un ShoppingCartItem. Y este ShoppingCartItem es el que va a tener asignado este v-for y este key. De tal manera que vamos a tener un ShoppingCartItem por cada detalle. Para que esto funcione, el ShoppingCartItem tendrá un template. Y este template estará conformado justamente por un v-list-item, de esta manera. ¿De qué manera podemos usar este ShoppingCartItem?, bueno tenemos que definirlo, tenemos que importar tal como está aquí en la línea 4 y tenemos también que definir aquí en components una referencia indicando que vamos a usar este componente, luego aquí debajo ya podemos usarlo con esta sintaxis o si queremos con esta otra sintaxis, ¿sí?. Yo lo pondré en mayúsculas para que se diferencia del resto de componentes que vienen de Vuetify. Entonces, ahora que hemos separado cada item en un componente nuevo, ahora vamos a poder gestionar con mayor facilidad cada item, ¿sí?. Para esto tenemos que definir una sección de script indicando que estamos haciendo uso de typescript y vamos a hacer que este cart item reciba como prop a un detalle, cuando usamos Options API, lo primero es definir un objeto a través de export default. Aquí nosotros ya podemos definir los props. Vamos a definir, por ejemplo, un prop llamado detail. Como ya hemos visto en lecciones anteriores, la manera de definir un prop es de esta manera. Entonces aquí dentro de nuestro objeto props, vamos a agregar un prop para el detalle. Cada item va a encargarse de pintar un detalle del carrito de compras. Para usar proptype, tenemos que importarlo de esta manera. Y aquí ya podemos definir nuestro tipo. En este caso será un card detail. Y como es obligatorio, pondremos require true. Como ahora el item tiene su propio componente, los eventos de clic tienen que llamar estos métodos desde este componente. Por lo tanto nos vamos a llevar esta sección de métodos, porque ya no se necesitan aquí en ShoppingCart, pero sí se necesitan aquí en ShoppingCartItem. Para que esto funcione tenemos que importar map actions desde Pinia. De la misma manera, tenemos que importar nuestro store. Y aquí obtenemos un error, porque este ShoppingCartItem no está recibiendo la propiedad detail que exige. El componente exige una propiedad detail, porque es obligatorio. Tenemos entonces que pasarle dicha propiedad. Aquí vamos a poner detail, igual detail. Ya que estamos leyendo cada uno de los detalles desde el store. Seguimos leyendo los detalles desde ShoppingCart, pero iteramos y a cada cart item sólo le pasamos un detalle a la vez, como aquí se indica. Si actualizamos en el navegador, vemos que nuestro proyecto continúa funcionando correctamente, la única diferencia es que ahora tenemos un ShoppingCart general que representa esta tarjeta y luego tenemos un ShoppingCartItem que representa a cada item de nuestro carrito de compras. Dentro de este list-item vamos a agregar una etiqueta v-img tal como lo hicimos anteriormente para nuestras tarjetas ¿sí?, vamos a poner por aquí v-img. Este v-img tendrá un atributo source simplemente con la url de la imagen del producto. Para que esto funcione, tenemos que definir una Computed Property. Esta Computed Property la tenemos que generar en este caso a partir de la propiedad detail que estamos recibiendo. Por lo tanto, vamos a poner aquí return this.detail,product.image y en caso que no haya una imagen, podemos proporcionar una imagen por defecto. Vamos a agregar entonces por ejemplo una silla y en nuestro carrito ya vemos la imagen. Sin embargo, la imagen ocupa mucho espacio. Eso es porque no hemos limitado el tamaño de este etiqueta v-img. Vamos a ponerle una altura de 40 píxeles. Como queremos de hecho que esta imagen sea circular, vamos a encerrarla dentro de un etiqueta v-avatar. Y para que el círculo no se vea mal, en este caso v-avatar acepta una propiedad size con el tamaño que queremos que tenga el avatar. Entonces no necesitamos aplicar estilos sobre la imagen, sino más bien un size sobre el avatar.

¿Tienes dudas?

Publicar pregunta

¡Comparte conocimiento!

X

Volver al índice

Regístrate

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

Capítulos





















































































85

Refactor: ShoppingCartItem







































Espera un momento 🎁 ...

¿Te gustaría aprender a programar, gratis?

Mago de Programación y más

Sólo debes registrarte 😉.