Proyecto cliente SPA para la API de películas con Nuxt.js

Adaptando el componente Card

Vamos a preparar el componente central en torno al que gira la SPA, la tarjeta para las películas.

El componente que ahora crea esa cajita en la portada se llama Card, el mismo que tiene esta estructura en Bulma. Tal como está no nos sirve, necesitamos adaptarla un poco.

Lo primero que podemos hacer es cambiarle el nombre, en lugar de Card.vue podríamos llamarla Peli.vue.

Obviamente al cambiarle el nombre dejará de funcionar, tendremos que adaptarlo al importarlo:

pages/index.vue

import Peli from '~/components/Peli'

export default {
  components: {
    Peli
  }
}

Y al usarlo:

<Peli
  title="Free"
  icon="github-circle"
>
  Open source on 
  <a href="https://github.com/buefy/buefy"> GitHub</a>
</Peli>

¿Creamos algunas pelis de prueba? Mockup data que se dice.

Vamos a añadir una lista con objetos simulando lo que recibiremos de la API, cada uno formado por los campos: id, título, favoritos, imagen, estreno y resumen.

Podéis copiarlos tal cual os los dejo aquí abajo:

 data: function () {
   return {
     'pelis': [
       {
         'id': 1,
         'titulo': 'El Padrino',
         'favoritos': '3',
         'imagen': 'https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY268_CR3,0,182,268_AL_.jpg',
         'estreno': '1972',
         'resumen': 'The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son.',
       },
       {
         'id': 2,
         'titulo': 'El Padrino: Parte 2',
         'favoritos': '1',
         'imagen': 'https://m.media-amazon.com/images/M/MV5BMWMwMGQzZTItY2JlNC00OWZiLWIyMDctNDk2ZDQ2YjRjMWQ0XkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY268_CR3,0,182,268_AL_.jpg',
         'estreno': '1974',
         'resumen': 'The early life and career of Vito Corleone in 1920s New York City is portrayed, while his son, Michael, expands and tightens his grip on the family crime syndicate.',
       },
       {
         'id': 3,
         'titulo': 'El Padrino: Parte 3',
         'favoritos': '0',
         'imagen': 'https://m.media-amazon.com/images/M/MV5BNTc1YjhiNzktMjEyNS00YmNhLWExYjItZDhkNWJjZjYxOWZiXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UX182_CR0,0,182,268_AL_.jpg',
         'estreno': '1990',
         'resumen': 'In the midst of trying to legitimize his business dealings in New York City and Italy in 1979, aging Mafia Don Michael Corleone seeks to avow for his sins, while taking his nephew Vincent Mancini under his wing.',
       }
     ]
   }
 },

Ahora necesitamos iterar este array y enviar los datos de cada peli al componente. Es muy fácil:

<Peli
 v-for="peli in pelis"
 :key="peli.id"
 :peli="peli"
/>

Usando el v-for repetimos el componente para cada película que guardamos en peli. El v-for requiere indicar una :key única para identificar cada componente, le podemos asignar la id de la película. Por último podemos enviar una propiedad con todo el objeto peli al componente.

Con esto veremos que se crean 3 cajas, pero sin contenido. Lo que debemos hacer es adaptar el componente para extraer los datos de la propiedad peli y hacer uso de ellos:

export default {
 props: {
   peli: {
     type: Object
   }
 },
}

La estructura de la película es algo más tediosa de programar porque requiere código de Bulma, os voy a facilitar un template básico para no liarnos demasiado:

components/Peli.vue

<template>
 <div class="column is-full-mobile is-half-tablet 
             is-one-third-desktop is-one-quarter-widescreen">
   <div class="card">
     <header class="card-header">
       <p class="card-header-title">{{ peli.titulo }}</p>
     </header>
     <div class="card-image">
       <figure class="image">
         <img :src="peli.imagen">
       </figure>
     </div>
     <footer class="card-footer">
       <a class="button is-light card-footer-item">
         <span>{{ peli.favoritos }}</span>
         <b-icon icon="star"></b-icon>
       </a>
     </footer>
   </div>
 </div>
</template>

Este diseño se adapta a las diferentes pantallas usando la grid de columnas de Bulma, parecido a como funciona Boostrap.

Sea como sea ya deberían aparecer las películas, lo malo es que nos surgirá un pequeño problema al estrechar la pantalla, y es que desaparecen las pelis horizontalmente.

El fallo lo podemos solucionar fácilmente indicando que el contenedor de columns en el index.vue acepta multilíneas:

pages/index.vue

<div class="columns is-multiline">