Nuxt.js|LightBox

Nuxt.jsでLightBoxを実装

vue-image-lightboxを使用。

インストール

npm install vue-image-lightbox vue-lazyload

plugins

/pluginsフォルダ下にインポート用のjsファイルを作成する。

なおこの時点でvue-image-lightboxはimportしない(後述)

例)/plugins/main.js

import Vue from 'vue'
import VueLazyLoad from 'vue-lazyload'

Vue.use(VueLazyLoad)

nuxt.config.js

設置したプラグインファイルの読み込みをnuxt.config.jsに記述する

plugins: [
  { src: '~/plugins/main.js' }, 
],

Vueファイル

使用するページのVueファイルに以下を記述

script

<script>
require("vue-image-lightbox/dist/vue-image-lightbox.min.css")//css読み込み
export default {
  components: { 
    LightBox:() => process.client ? import('vue-image-lightbox') : null,
  },
  data() {
    return {
      media: [
        {
          tuhmb:"サムネイル画像のパス",
          src:"画像のパス"
         },
       ],
    }
  },
  methods: {
    showLightbox(index) {
      this.$refs.lightbox.showImage(index);
    },
  }
}
</script>

vue-image-lightboxのimportとcomponent指定

上記の以下の部分についての理由を詳述

  components: { 
LightBox:() => process.client ? import('vue-image-lightbox') : null,
},
SSRエラーの回避

vue-image-lightboxはコード内にwindowを使用しているため、SSR(サーバーサイドレンダリング)ではエラーとなる。そこでクライアント側でだけimportするよう、component定義時にprocess.clientでの判定を噛ませて読み込みを行っている。

lazy-lordの読み込みのように別ファイルにしてnuxt.config.jsのpluginsのパラメータとしてmode:’client’を使用する方法もあり、試したところimportは問題ないがcomponent定義がうまくいかず断念。

plugins: [ 
  { src: '~/plugins/vue-image-lightbox.js', mode: 'client' }
]
typeエラーの回避

vue-image-lightboxには型定義が無いため、通常のimportを行うとTypeScriptのtypeエラーが発生するが、この記述によりそのエラーも回避できる。

TypeScriptの型定義エラーについては以下のような対処法があるが、今回は上記記述のみで回避できたため以下の対応は行っていない。※しかも現状で理屈を十分に理解できてない

メモとして残しておく。

@typesからインストールする。

具体的には以下。

npm install --save @types/vue-image-lightbox

実行するとエラーとなるので、vue-image-lightboxでは型定義ファイルは提供されていないと思われる。

型定義ファイル( d.ts )を自作する

今回は試していない。

requireでモジュールを読み込む

具体的には以下。

const LightBox = require('vue-image-lightbox')

これによりコンパイルエラーは回避できたが、上記のSSRエラーはいずれにしろ回避できないため使用せず。

テンプレート

mediaという配列に表示する画像のサムネイル、画像のパスがオブジェクト形式で格納されているという前提で、以下のように記述する。

<template>
<div class="container">
<div v-for="(image, index) in media" :key="index">
  <img :src="'/images/' + image + '.jpg'" alt="" @click="showLightbox(index)">
</div>
<client-only>
<LightBox
  ref="lightbox"
  :media="images"
  :showLightBox="false"
  :showThumbs="false"
></LightBox>
</client-only>
</div>
</template>

画像一覧オブジェクトの形式は以下。

[
  {
    thumb: 'http://example.com/thumb.jpg',
    src: 'http://example.com/image.jpg',
    caption: 'caption to display. receive <html> <b>tag</b>', // Optional
    srcset: '...' // Optional for displaying responsive images
  },
]

LightBoxコンポーネントについてはクライアント側でのみ読み込まれるので、テンプレート側でもクライアント側での処理となる記述を加える。

<client-only>
  コンポーネント
</client-only>

以上でいけるはず。なんか忘れてたらまた追記。