Uno de los valores que nos devuelve la API del juego cuando le pedimos los datos de un jugador es el progreso. Esto nos indica el estado de los actos (hay cinco), es decir, si los ha completado o no.
Vamos a crear un componente, muy sencillo, que nos indique si el usuario ha completado un acto o no. Para indicar si el acto está completado o no usaremos una imagen (Sprites CSS), que estará oscurecida y con un candado cuando esté sin completar y sin el candado y bien clara cuando esté completado.
La imagen que usaremos como Sprite CSS es esta:
Lo primero que vamos a hacer es crear los estilos CSS, en nuestro fichero global de CSS, /assets/main.styl. Vamos a añadir el siguiente contenido:
Hemos creado unas clases CSS que nos van a permitir mostrar la imagen correspondiente a cada acto y sus dos estados: pending (sin completar) y done (completado). Si queremos mostrar el acto dos completado lo que tenemos que hacer es tan sencillo como darle las clases "act act2 done".
Esto nos mostraría la porción de imagen correspondiente al acto 2 completado, que lo estamos controlando con la propiedad CSS de background-positon.
Ahora tenemos que crear los archivos y directorios que vamos a utilizar con este componente de progreso de la historia del juego. Cuando juegas a Diablo III puedes subir niveles y hacer misiones especiales sin necesidad de completar la historia del juego.
Es por eso que implementamos este componente. Para ello, al mismo nivel del directorio /TopHeroes, creamos un directorio llamado /ProgressList. Dentro de este, creamos 2 ficheros: Index.vue y ProgressItem.vue.
Fíjate que no viene ordenado por actos, por lo que vamos a tener que realizar esta tarea de ordenamiento antes de poder iterar sobre el objeto de progression.
Lo primero que vamos a hacer es usar el componente (aunque esté vacío) en el componente padre, es decir, en /MainBlock/Index.vue. Los 3 pasos de siempre. Importar, habilitar, utilizar.
Todo lo que tiene este componente no requiere explicación, puesto que es un componente muy sencillo.
A modo de resumen este componente tiene definidas una prop, que son los actos, que los ordenamos a través de la función sortedActs (aunque en realidad es una computed property).
En el HTML iteramos sobre este objeto que contiene los actos ordenados del uno al cinco y cada elemento corresponde a otro componente (ProgressItem, que vamos a ver ahora) que recibe como parámetro un objeto con el acto (ej. act2) y el valor (ej. true).
El componente ProgressItem.vue tiene el siguiente contenido:
Aunque este componente es bastante sencillo, vamos a comentar un par de cosas:
La prop act tiene una función de validación distinta a las que hemos visto anteriormente. No es gran cosa, pero está comprobando que el numero de claves del objeto que recibe sea igual a 2. Muy simple.
La computed propertyactTitle nos devuelve un String dependiendo del valor del acto, es decir, si está completado o no. Para poder ver este texto, deberías dejar el ratón encima de dicho elemento unos segundos.
Lo diferencial de esto es que estamos incluyendo emojis (íconos) en el texto. ¡Sí! Los emojis los podemos usar como texto normal, usando las comillas, como si de un texto se tratara. 🤘😏🤘
Exceptuando un par de cosas, estos componentes que acabamos de crear no tenían complejidad alguna. Si has seguido todos los pasos correctamente, la app debería verse así:
Modificando los valores desde las Vue DevTools en el navegador, para ver ambos estados en acción:
Y esto sería todo. Ahora vamos a empezar con el bloque de la derecha de nuestro grid, donde trabajaremos con los stats del usuario y el tiempo jugado por héroe.
Quédate con lo de los emojis en mente, pues los volveremos a utilizar más adelante.
Jorge, viendo que los componentes es lo que mas abunda, casi todo lo podemos volver un componente, ¿Que criterios tomas y/o recomiendas para decidir si algo lo pasas a un componente por separado?
Pues cuanto más pequeño sea tu componente mejor, pues luego, cuando tengas que testear tu componente es más sencillo.
Hay varios "indicadores" para saber cuando un componente debería ser divido en algo más pequeño. El indicador que casi nunca falla es este: "Si en alguna parte de la aplicación no puedes usar una computed property y te ves obligado a usar un method porque necesitas pasarle parámetros, entonces necesitas un componente más pequeño". Obviamente esto no aplica a botones o acciones que necesitan de un método. Durante el curso no pude atomizar al máximo todos los componentes porque se hacía muy pesado para escribir (y por tanto para leer), y en muchos casos no se han llegado a crear componentes pequeños. Pero desde mi experiencia, cuanto más pequeños mejor. De todas formas, lo iras viendo con la experiencia. Tampoco se trata de que cada etiqueta HTML la metas en un componente 😅. Hay que ser prácticos, pero por norma general, cuanto más sencillo el componente, mejor.
Esta clase fue cortita y básica, me gusta, con las otras clases me llevé una hora aproximadamente leyendo y entendiendo bien todo jaja, aunque no comprendo muy bien a que se refería con la parte de que los actos no estaban ordenados, es decir, yo los veo ordenados D:
No recuerdo bien, pero creo que era porque no siempre llegaban en orden, es decir el array podia tener primero el acto 5 y segundo el acto 3. Creo recordar que los ordenamos en el proyecto.
Estuve buscando el error de por que las imagenes se veian blancas y era por que tenia el modo oscuro de mi navegador activado :D
Hahaha me paso lo mismo! Si no es por tu comentario seguiría revisando los estilos del código. Gracias!
Recuerden quitar el atributo "Scoped" (Aislar solamente a este componente) de la parte de CSS del Componente ProgressList/Index.vue, ya que al contener las clases que utilizaremos para su hijo ProgressItem.vue necesitamos que los los estilos puedan "salir" desde este componente 👍🏻
Cuando creo un nuevo componente desde el editor, me incluye el scoped, puede ser que alguno se haya colado y no sea necesario, como bien dices.
Se le puede agregar el /deep/ o :v-deep(.class) en vue 3.
A la clase .act en main.styl falta añadir:
.act
...
width 50px height 55px margin 0 auto
...
A alguien le quedaron los estilos asi?
¿Como se cambia el valor al act de true a false con las Vue DevTools?
!Vue DevTools
El valor lo puedes cambiar "a mano" o haciendo click (tipo on/off) y te alterna entre true/false
no me mostraba las imagenes de progress, tenia un error de indentacion en el archivo /ProgressList/Index.vue, EsLint no me lo corrigio automaticamente hasta que copie y pegue por partes el codigo del maestro: