Galleria di immagini con Vue

In questa lezione impareremo a realizzare una galleria di immagini con Vue. Le gallerie di immagini sono un elemento comune su molti siti web, che consentono agli utenti di visualizzare e navigare attraverso diverse immagini in modo intuitivo. Nel tutorial JavaScript di questo blog, ho già sviluppato una galleria di immagini che potete consultare al seguente link: https://www.codingcreativo.it/galleria-di-immagini-con-filtri/

Creazione della Galleria di Immagini con Vue

Iniziamo creando un nuovo progetto Vue.js e aggiungendo la nostra galleria di immagini. Quindi, esegui i seguenti comandi nel terminale:

vue create gallery-app

Seguiamo le istruzioni per l’installazione del nuovo progetto e poi entriamo dentro la cartella:

cd gallery-app

Dopo creiamo il componente per la galleria di immagini dove utilizziamo la direttiva v-for per iterare attraverso l’array di immagini e visualizzarle nella nostra galleria. Le immagini inoltre vengono filtrate in base alla categoria corrente utilizzando il metodo filterImages. Abbiamo cura di garantire che quando il componente è creato le immagini siano tutte visibili. Dopo creiamo il metodo showImage che controlla se l’immagine deve essere mostrata, in base alla categoria selezionata. Le immagini vengono visualizzate o nascoste dunque utilizzando la direttiva v-show.

Personalizziamo infine il CSS per rendere la galleria di immagini responsive e stilizzata.

Ecco di seguito il codice di esempio:

<template>
  <div class="container-gallery">
    <h2>Galleria di Immagini</h2>
    <div class="gallery-menu">
      <a @click="filterImages('all')">Tutte</a>
      <a @click="filterImages('fiori')">Fiori</a>
      <a @click="filterImages('animali')">Animali</a>
    </div>
  
    <div class="gallery">
      <img v-for="(image, index) in images" :key="index" class="image" :src="image.src" :alt="image.alt" :class="image.category" v-show="showImage(image.category)">
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      images: [
        { src: '...', alt: 'Immagine Fiori 1', category: 'fiori' },
        { src: '...', alt: 'Immagine Animali 1', category: 'animali' },
        { src: '...', alt: 'Immagine Animali 2', category: 'animali' },
        { src: '...', alt: 'Immagine Fiori 2', category: 'fiori' },
        { src: '...', alt: 'Immagine Fiori 3', category: 'fiori' },
        { src: '...', alt: 'Immagine Animali3', category: 'animali' }
      ],
      currentCategory: 'all'
    };
  },
  methods: {
    filterImages(category) {
      this.currentCategory = category;
    },
    showImage(category) {
      return this.currentCategory === 'all' || category === this.currentCategory;
    }
  },
  created() {
    this.filterImages('all');
  }
};
</script>

<style scoped>
.container-gallery {
  max-width: 800px;
  margin: 20px auto;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  overflow: hidden;
}

h2 {
  text-align: center;
  color: #4CAF50; 
  margin: 20px 0;
}

.gallery-menu {
  text-align: center;
  padding: 10px;
  background-color: #4CAF50; /* Green */
}

.gallery-menu a {
  text-decoration: none;
  color: #fff;
  padding: 10px 20px;
  margin: 0 10px;
  cursor: pointer;
  border-radius: 5px;
  transition: background-color 0.3s ease;
}

.gallery-menu a:hover {
  background-color: #45a049; 
}

.gallery {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

.image {
  max-width: 220px;
  width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
</style>

Galleria di Immagini con Vue con più componenti

È possibile suddividere il codice in più componenti per renderlo più modulare e manutenibile. Ecco dunque un esempio di come si potrebbe suddividere il codice in due componenti: uno per la galleria stessa e uno per il singolo elemento dell’immagine.

Realizziamo dapprima il componente GalleryFilter.vue:

<template>
  <div class="container-gallery">
    <h2>Galleria di Immagini</h2>
    <Menu @filter="filterImages" />
    <div class="gallery">
      <ImageItem v-for="(image, index) in filteredImages" :key="index" :image="image" />
    </div>
  </div>
</template>

<script>
import Menu from './MenuItems.vue';
import ImageItem from './ImageItem.vue';

export default {
  components: {
    Menu,
    ImageItem
  },
  data() {
    return {
      images: [
        { src: '...', alt: 'Immagine Fiori 1', category: 'fiori' },
        { src: '...', alt: 'Immagine Animali 1', category: 'animali' },
        { src: '...', alt: 'Immagine Animali 2', category: 'animali' },
        { src: '...', alt: 'Immagine Fiori 2', category: 'fiori' },
        { src: '...', alt: 'Immagine Fiori 3', category: 'fiori' },
        { src: '...', alt: 'Immagine Animali3', category: 'animali' }
      ],
      currentCategory: 'all'
    };
  },
  computed: {
    filteredImages() {
      if (this.currentCategory === 'all') {
        return this.images;
      } else {
        return this.images.filter(image => image.category === this.currentCategory);
      }
    }
  },
  methods: {
    filterImages(category) {
      this.currentCategory = category;
    }
  },
  created() {
    this.filterImages('all');
  }
};
</script>

Poi creiamo un componente per il menù di navigazione, MenuItems.vue:

<template>
  <div class="gallery-menu">
    <a @click="filter('all')">Tutte</a>
    <a @click="filter('fiori')">Fiori</a>
    <a @click="filter('animali')">Animali</a>
  </div>
</template>

<script>
export default {
  methods: {
    filter(category) {
      this.$emit('filter', category);
    }
  }
};
</script>

<style scoped>
.gallery-menu {
  text-align: center;
  padding: 10px;
  background-color: #4CAF50; /* Green */
}

.gallery-menu a {
  text-decoration: none;
  color: #fff;
  padding: 10px 20px;
  margin: 0 10px;
  cursor: pointer;
  border-radius: 5px;
  transition: background-color 0.3s ease;
}

.gallery-menu a:hover {
  background-color: #45a049; 
}
</style>

Ed un altro componente per le immagini, ImageItem.vue:

<template>
  <img class="image" :src="image.src" :alt="image.alt">
</template>

<script>
export default {
  props: {
    image: Object
  }
};
</script>

<style scoped>
.image {
  max-width: 220px;
  width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
</style>

Corso su JavaScript

Conclusioni

In questo articolo, abbiamo esplorato come creare una galleria di immagini utilizzando Vue. Abbiamo iniziato con un esempio di codice che mostra una galleria di immagini filtrabile per categorie. Abbiamo quindi discusso di come questo codice possa essere ulteriormente migliorato attraverso la suddivisione in componenti separati.

La suddivisione del codice in componenti offre diversi vantaggi, tra cui una maggiore modularità, facilità di manutenzione e riutilizzo del codice. Abbiamo creato tre componenti separati: GalleryFilter.vue, Menuitems.vue e ImageItem.vue, ciascuno dei quali si occupa di una parte specifica della funzionalità della galleria.

Infine, abbiamo visto come utilizzare le proprietà dei componenti e gli eventi personalizzati per consentire una comunicazione efficace tra i componenti. Questo approccio favorisce una migliore separazione delle responsabilità e rende il codice più leggibile e manutenibile.

Spero che questo articolo vi abbia fornito una buona comprensione di come utilizzare Vue.js per creare una galleria di immagini interattiva e come strutturare il codice in componenti separati. Con un po’ di pratica e creatività, si può espandere e personalizzare ulteriormente questa galleria per adattarla alle vostre esigenze specifiche. Buon coding!

Alcuni link utili

Corso linguaggio JavaScript

Libro JavaScript

Tutorial JavaScript

Componenti Vue.js

Option API

Composition API

Counter in Vue.js (con le due sintassi: Option API e Composition API)

Direttiva v-model

props con Option API