DEV Community

Matthew Piercey for OverScore Media

Posted on • Edited on

Nuxt, Meet Vue-Picture-Swipe

This article is part of a series on my experiences with Nuxt.js that I built into the nuxt-toolkit by OverScore Media

GitHub logo overscore-media / nuxt-toolkit

A bunch of useful example code snippets for use with Nuxt.js

See a live example at https://nuxt-toolkit.overscore.media! :]


Ah, the photo gallery. Once an actual place, the concept can now fit in the palm of your hand. Or on your lap. Or desk. I guess the analogy kinda falls apart there, but you get the point - including a photo gallery in your website can go a long way to improving its fun and usability.

Photos can help make otherwise uncertain concepts clearer, and they "speak" in ways textual characters would be hard-pressed to. Unless they're ASCII art... Point is, pictures are nice, and you want them in your Nuxt project.

Well, you're in luck. Granted, there are a lot of ways of doing this (some better than others, and likely some better than this one), but I can confirm that it works, and it works pretty well for my application. Let's get to it!

Get the Library

yarn add vue-picture-swipe or npm install --save vue-picture-swipe. You know the drill by now...

GitHub logo rap2hpoutre / vue-picture-swipe

🖼 Vue Picture Swipe Gallery (a gallery of image with thumbnails, lazy-load and swipe) backed by photoswipe

Make the Nuxt Plugin

I named it gallery.js and put it in the ~/plugins/ folder of my Nuxt app. I then imported it in my nuxt-config.js like so:

// ...
plugins: [
  { src: '~/plugins/gallery', mode: 'client' }
],
// ...
Enter fullscreen mode Exit fullscreen mode

And, that's it!

Wait, you want the code for the plugin? Kids these days...

Fine. But only because I'm in a good mood. Take it, why don't ya?

import Vue from 'vue'
import VuePictureSwipe from 'vue-picture-swipe'

Vue.component('Gallery', {
  components: {
    VuePictureSwipe
  },
  props: {
    imgs: {
      type: Array,
      required: true
    },
    options: {
      type: Object,
      required: false,
      default () {
        return {
          bgOpacity: 0.95,
          shareEl: true,
          zoomEl: true
        }
      }
    }
  },
  template: `<vue-picture-swipe :items="imgs" :options="options" />`
})
Enter fullscreen mode Exit fullscreen mode

The Implementation of it All

Alright, once you've got all that setup, you should be able to use the Gallery component anywhere in your Nuxt app. Sure, you could make it just another component and import it only where you need it, but...

Imma be honest, I needed it to be a global component for my use case, so that's how I set it up. But the logic is basically the same for making it a local single-file component. Like so, I guess:

<!-- ~/components/Gallery.vue -->
<template>
  <client-only>
    <vue-picture-swipe :items="imgs" :options="options" />
  </client-only>
</template>

<script>
import VuePictureSwipe from 'vue-picture-swipe'

export default {
  name: 'Gallery',
  components: {
    VuePictureSwipe
  },
  props: {
    imgs: {
      type: Array,
      required: true
    },
    options: {
      type: Object,
      required: false,
      default () {
        return {
          bgOpacity: 0.95,
          shareEl: true,
          zoomEl: true
        }
      }
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

Something like that. Then you could import it with import Gallery from '~/components/Gallery' and use it only where you need it (no need to edit the nuxt.config.js in that case).

Your call. Either way, here's how you actually use the component in practice:

<Gallery :imgs="[{src: 'https://picsum.photos/200/300', thumbnail: 'https://picsum.photos/200/300', w: 200, h: 300, alt: 'random picture from picsum.photos to demonstrate the vue-picture-swipe component', title: 'Some Picture'}, {src: 'https://picsum.photos/200/300', thumbnail: 'https://picsum.photos/200/300', w: 200, h: 300, alt: 'random picture from picsum.photos to demonstrate the vue-picture-swipe component', title: 'Some Picture'}]" />
Enter fullscreen mode Exit fullscreen mode

Yes, that seems like a giant unruly string (and it is; you can obviously outsource such logic to your component/page/layout data () but I'm just using it inline here), but here's the run-down:

:imgs is the array of image objects, which contain:

  • src is an individual image's, welll... source. Like it's URL.
  • thumbnail is a scaled-down version of the image to show before you click on it and make it full-screen. If you don't have a thumbnail as such, you can use the same URL like I did.
  • w is the image's width (in pixels).
  • h is the image's pixel height.
  • alt is the ever-important alt text for accessibility purposes.

Also, this is some CSS I added to spruce things up a bit:

.pswp__bg {
  background-color: #2f2f2f;
}

.my-gallery {
  display: flex;
  flex-flow: row wrap;
  figure {
    flex-grow: 1;
    min-width: 20%;
    margin-left: 5px;
    margin-right: 5px;
    a {
      img {
        border-radius: 10px;
        box-shadow: 5px 3px 5px #2f2f2f;
        &:hover {
          transform: scale(1.05);
          box-shadow: 5px 3px 5px #c9c3b2;
          transition: all 0.15s ease-in-out;
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That'll give the images a little border and animation when you hover over them with your mouse, and the flex stuff is my way of spreading the images out enough so they aren't all clumped together, but putting as many of them that can comfortably fit together on the same line.

Fair warning - the images I used in this example are probably not great sizes for this, but that's why it's an example! (of what not to do?)

Anyway, I hope you got something out of this. Keep safe and healthy, and keep on coding!

Top comments (0)