【Vue.js】vue-image-lightbox で画像ギャラリーを作成！

## はじめに
Googleドライブの画像表示みたいなUIを作りたいと思っていたところ、vue-image-lightbox を使うと
簡単に実現できたので、最低限の実装方法を残したいと思います。

## vue-image-lightboxとは？
サムネイルから、画像を拡大表示したり、スライドショーにしたりするための機能を提供しているライブラリです。

## 参考情報
- vue-image-lightbox
　https://www.npmjs.com/package/vue-image-lightbox
- ソースコード
　https://github.com/ryuckel/vue-playground/tree/vue-image-lightbox

## 今回の記事で実現した内容
以下の画像のようになるところをゴールとします。
記事中は主にライブラリに関係した部分を書いてます。ソースは参考情報から見てみてください。
![画面収録 2020-02-18 12.19.11.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125532/d8dadf38-a023-59ee-03da-0f1915eb7d88.gif)


## 環境
- Vue.js 2.5.10
- vue-cli 3.7.0

## 実装（準備編）
- 環境構築
<br>vue createコマンドでプロジェクトを作成していきます。
<br>プロジェクト名は任意で入れてください。
<br>セットアップにあたり聞かれる質問も任意で答えていただいて構いません。

```
vue create image-app(プロジェクト名を入れてください)
cd image-app
```


- 必要なライブラリのインストール

```
yarn add vue-image-lightbox vue-lazyload
```
※画像の遅延読み込み(Webページを先に表示して画像は読み込んだら表示させること)が必要になるため
vue-lazyloadも併せてインストールしています。

- CSSのインポート
<br>まず、app.scssにvue-image-lightboxのCSSプロパティを読み込みます。

```app.scss
@import '../../../node_modules/vue-image-lightbox/dist/vue-image-lightbox.min.css';
```

- vue-lazyloadのインポート
<br>画像の遅延読み込みのため、main.jsにvue-lazyloadをインポートしていきます。

```main.js
import VueLazyLoad from 'vue-lazyload';
Vue.use(VueLazyLoad);
```

## 実装（コンポーネント作成）

vue-image-lightboxを使用したコンポーネントを作成します。
CSSはBuefy(BulmaベースのUIコンポーネントライブラリ)を使い、サムネイルだけCSSを当てています。
要点は以下の通りです。

- import文でvue-image-lightboxを読み込みます。
- 画像表示は配列(images)を用意して```v-for```でimg要素を生成し、v-lazyで遅延読み込みしています。
- img要素をクリックすると```openGallery```メソッドを発火させることでクリックした画像がギャラリー表示されます。
　openGalleryメソッドはvue-image-lightboxのshowImageメソッドに配列(images)のインデックスを渡しています。
- ImageLightBox要素で指定しているプロパティ```show-light-box```がtrueだとブラウザにページを読み込んだタイミングでギャラリー表示されます。
- ```show-caption```がtrueにすると、ギャラリー表示時に画像オブジェクトに指定されたcaptionが表示されます。

```LightBox.vue
<template>
	<div>
		<div class="media">
			<div class="column">
				<div class="columns is-multiline">
					<div v-for="(image, index) in images" :key="image.id" class="column is-one-quarter has-text-centered">
						<img v-lazy="image.src" @click="openGallery(index)" class="thumbnail" />
						<p>{{ image.title }}</p>
					</div>
				</div>
				<ImageLightBox ref="lightbox" :images="images" :show-light-box="false" :show-caption="true"></ImageLightBox>
			</div>
		</div>
	</div>
</template>

<script>
import ImageLightBox from 'vue-image-lightbox';

export default {
	name: 'LightBox',
	components: {
		ImageLightBox
	},
	data() {
		return {
			images: [
				{
					thumb: 'https://www.pakutaso.com/shared/img/thumb/YAMAhokkaido015_TP_V.jpg',
					src: 'https://www.pakutaso.com/shared/img/thumb/YAMAhokkaido015_TP_V.jpg',
					title: '朝日が昇る摩周湖（北海道川上郡弟子屈町）',
					caption: '朝日が昇る摩周湖（北海道川上郡弟子屈町）',
					id: 1
				},
				{
					thumb: 'https://www.pakutaso.com/shared/img/thumb/YAMAhokkaido032_TP_V.jpg',
					src: 'https://www.pakutaso.com/shared/img/thumb/YAMAhokkaido032_TP_V.jpg',
					title: '水鏡の青い池（北海道川上郡美瑛町白金）',
					caption: '水鏡の青い池（北海道川上郡美瑛町白金）',
					id: 2
				},
				{
					thumb: 'https://www.pakutaso.com/shared/img/thumb/KMKC428D354_TP_V.jpg',
					src: 'https://www.pakutaso.com/shared/img/thumb/KMKC428D354_TP_V.jpg',
					title: '悪天候の上高地と大正池',
					caption: '悪天候の上高地と大正池',
					id: 3
				}
			]
		};
	},
	methods: {
		openGallery(index) {
			this.$refs.lightbox.showImage(index);
		}
	}
};
</script>
<style lang="scss" scoped>
img.thumbnail {
	height: 100px;
	cursor: pointer;
}
</style>
```

## 最後に
画像のギャラリー表示をやりたくなった時になかなかvue-image-lightboxに行きつけなかったのですが、
vue-image-lightboxを見つけてから実装まではスムーズにいったので記事にしてみました。
ぜひお試しください！