Nuxt, Meet Vue-Picture-Swipe
Tags: nuxt, vue, javascript, images
Published: 2020-04-14 20:33:08

This article is part of a series on my experiences with Nuxt.js that I built into the [nuxt-toolkit](https://github.com/overscore-media/nuxt-toolkit) by [OverScore Media](https://overscore.media) {% github https://github.com/overscore-media/nuxt-toolkit no-readme %}

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 https://github.com/rap2hpoutre/vue-picture-swipe no-readme %}

## 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:

```js
// ...
plugins: [
  { src: '~/plugins/gallery', mode: 'client' }
],
// ...
```

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?

```js
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" />`
})
```

## 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:

```vue
<!-- ~/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>
```

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:

```vue
<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'}]" />
```

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:

```scss
.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;
        }
      }
    }
  }
}
```

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!