vue-easy-lightbox

A Vue.js 3.0 image lightbox component with Zoom / Drag / Rotate / Switch .

vue-easy-lightbox@1.x only supports Vue.js 3, if you need Vue.js 2 version please check hereopen in new window.

Installation

Using npm or yarn

$ npm install --save vue-easy-lightbox@next
$ yarn add vue-easy-lightbox@next

Import in Browser

Add script in your browser and use the global variable VueEasyLightbox.

<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-easy-lightbox@next/dist/vue-easy-lightbox.umd.min.js"></script>
<script>
  const app = Vue.createApp({
    // ... root component options
  })
  app.use(VueEasyLightbox) // global variable
  app.mount('#app')
</script>

Different Builds

Since Vue 3.x uses ES2015 (docs faqopen in new window), there is no need to build ES5 bundle, and ES5 build is removed from version 1.6.0.

ModuleFilename
UMD(for browsers)vue-easy-lightbox.umd.min.js
CommonJSvue-easy-lightbox.common.min.js (pkg.main)
ES Module(for bundlers)vue-easy-lightbox.esm.min.js (pkg.module)

External CSS Build

Added in: v1.2.3

By default, CSS is included in dist/*.min.js. In some special cases you may want to import CSS individually to avoid some problems (CSP Violationopen in new window). You can import builds without CSS and individual .css file from dist/external-css/.

import VueEasyLightbox from 'vue-easy-lightbox/external-css'
// or
import VueEasyLightbox from 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js'

// you need to import css file
import 'vue-easy-lightbox/external-css/vue-easy-lightbox.css'
// or
import 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.css'

TypeScript Checking error:

If your project is TypeScript project and you get this error message:

Could not find the declaration file for module 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js'

Here are two ways to solve it.

Way 1: add d.ts in your project:

declare module 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js' {
  import VueEasyLightbox from 'vue-easy-lightbox'
  export * from 'vue-easy-lightbox'
  export default VueEasyLightbox
}

Way 2:

If you're using webpack: webpack alias docsopen in new window

// wepback.config.js
module.exports = {
  //...
  resolve: {
    alias: {
      'vue-easy-lightbox$': 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js',
    },
  },
};

// in your component
import VueEasyLightbox from 'vue-easy-lightbox' // work

vitejs: vitejs aliasopen in new window

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  resolve: {
    alias: {
      'vue-easy-lightbox$': 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js'
    }
  }
})

Usage

Using UMD in browser

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-easy-lightbox@next/dist/vue-easy-lightbox.umd.min.js"></script>
  </head>
  <body>
    <div id="app">
      <div class="">
        <div v-for="(src, index) in imgs" :key="index" class="pic" @click="() => showImg(index)">
          <img :src="src" />
        </div>
      </div>
      <vue-easy-lightbox :visible="visibleRef" :imgs="imgs" :index="indexRef" @hide="onHide"></vue-easy-lightbox>
    </div>
    <script>
      const { ref } = Vue
      const app = Vue.createApp({
        setup() {
          const visibleRef = ref(false)
          const indexRef = ref(0)
          const imgs = [
            'https://via.placeholder.com/450.png/',
            'https://via.placeholder.com/300.png/',
            'https://via.placeholder.com/150.png/',
            { src: 'https://via.placeholder.com/450.png/', title: 'this is title' }
          ]
          const showImg = (index) => {
            indexRef.value = index
            visibleRef.value = true
          }
          const onHide = () => visibleRef.value = false
          return {
            visibleRef,
            indexRef,
            imgs,
            showImg,
            onHide
          }
        }
      })
      // Registering VueEasyLightbox for your VueApp.
      app.use(VueEasyLightbox)
      app.mount('#app')
    </script>
  </body>
</html>

Basic Usage in SFC

1. Register VueApp component

In Vue.js 3.0. You need to register the vue-easy-lightbox for each VueApp you use. Docs hereopen in new window

import Vue from 'vue'
import VueEasyLightbox from 'vue-easy-lightbox'

const app = Vue.createApp({
  // ... root component options
})
app.use(VueEasyLightbox)
app.mount('#app')

2. Basic Usage

<template>
  <div>
    <button @click="showSingle">Show single picture.</button>
    <button @click="showMultiple">Show a group of pictures.</button>

    <vue-easy-lightbox
      :visible="visibleRef"
      :imgs="imgsRef"
      :index="indexRef"
      @hide="onHide"
    ></vue-easy-lightbox>
  </div>
</template>

<script>
// If VueApp is already registered with VueEasyLightbox, there is no need to register it here.
import VueEasyLightbox from 'vue-easy-lightbox'
import { ref, defineComponent } from 'vue'

export default defineComponent({
  components: {
    VueEasyLightbox
  },
  setup() {
    const visibleRef = ref(false)
    const indexRef = ref(0) // default 0
    const imgsRef = ref([])
    // Img Url , string or Array of string
    // ImgObj { src: '', title: '', alt: '' }
    // 'src' is required
    // allow mixing

    const onShow = () => {
      visibleRef.value = true
    }
    const showSingle = () => {
      imgsRef.value = 'http://via.placeholder.com/350x150'
      // or
      // imgsRef.value  = {
      //   title: 'this is a placeholder',
      //   src: 'http://via.placeholder.com/350x150'
      // }
      onShow()
    }
    const showMultiple = () => {
      imgsRef.value = [
        'http://via.placeholder.com/350x150',
        'http://via.placeholder.com/350x150'
      ]
      // or
      // imgsRef.value = [
      //   { title: 'test img', src: 'http://via.placeholder.com/350x150' },
      //   'http://via.placeholder.com/350x150'
      // ]
      indexRef.value = 0 // index of imgList
      onShow()
    }
    const onHide = () => (visibleRef.value = false)

    return {
      visibleRef,
      indexRef,
      imgsRef,
      showSingle,
      showMultiple,
      onHide
    }
  }
})
</script>

Custom buttons or toolbar

<vue-easy-lightbox ...>
  <template v-slot:prev-btn="{ prev }">
    <button @click="prev">show the prev</button>
  </template>

  <template v-slot:next-btn="{ next }">
    <button @click="next">show the next</button>
  </template>

  <template v-slot:close-btn="{ close }">
    <button @click="close">close lightbox</button>
  </template>

  <template v-slot:toolbar="{ toolbarMethods }">
    <button @click="toolbarMethods.zoomIn">zoom in</button>
    <button @click="toolbarMethods.zoomOut">zoom out</button>
    <button @click="toolbarMethods.rotateLeft">Anticlockwise rotation</button>
    <button @click="toolbarMethods.rotateRight">clockwise rotation</button>
  </template>
</vue-easy-lightbox>

Reference: Slots-Vue.jsopen in new window

Composables

Added in v1.7.0

useEasyLightbox() provides some simple methods and states to help you use setup(). It is optional. You can customize your state.

Usage:

<template>
  <div>
    <button @click="show">show</button>
    <vue-easy-lightbox
      :visible="visibleRef"
      :imgs="imgsRef"
      :index="indexRef"
      @hide="onHide"
    />
  </div>
</template>

<script>
import { defineComponent } from 'vue'
import VueEasyLightbox, { useEasyLightbox } from 'vue-easy-lightbox'

export default defineComponent({
  components: {
    VueEasyLightbox
  },
  setup() {
    const {
      // methods
      show, onHide, changeIndex,
      // refs
      visibleRef, indexRef, imgsRef
    } = useEasyLightbox({
      // src / src[]
      imgs: [
        'http://via.placeholder.com/250x150',
        'http://via.placeholder.com/300x150',
        'http://via.placeholder.com/350x150'
      ],
      // initial index
      initIndex: 0
    })

    return {
      visibleRef,
      indexRef,
      imgsRef,
      show,
      onHide
    }
  }
})
</script>

Type declaration

export interface Img {
  src?: string
  title?: string
  alt?: string
}
export interface UseEasyLightboxOptions {
  /**
   * image src/Img or list of images src/Img
   * @default ''
   */
  imgs: Img | string | (Img | string)[];
  /**
   * initial index of imgList
   * @default 0
   */
  initIndex?: number;
}
export declare const useEasyLightbox: (options: UseEasyLightboxOptions) => {
  imgsRef: Ref<Img | string | (Img | string)[]>;
  indexRef: Ref<number | undefined>;
  visibleRef: Ref<boolean>;
  show: (index?: Ref<number> | number | Event) => void;
  onHide: () => void;
  changeIndex: (index?: number) => void;
};

Options

Props

NameTypeDefaultDescription
visibleBooleanrequiredControl lightbox display
imgsString/String[]/ImgObject:{ src: string, title?: string, alt?: string }/ImgObject[]requiredImage's src / array of src / ImgObject:{ src, title?, alt? } / array of ImgObject / array of ImgObject.
indexNumber0Index of imgList
loopBooleanfalsePass true to enable continuous loop mode.
scrollDisabled (scroll-disabled)BooleantruePass true to disable scrolling when modal is visible.
escDisabled (esc-disabled)BooleanfalseBy default, press the esc key to close Modal during presentation.
moveDisabled (move-disabled)BooleanfalsePass true to disable image movement and enable swipe.
rotateDisabled (rotate-disabled)BooleanfalsePass true to disable image rotation.
zoomDisabled (zoom-disabled)BooleanfalsePass true to disable image zooming.
pinchDisabled (pinch-disabled)BooleanfalsePass true to disable pinching.
maskClosable (mask-closable)BooleantrueEnable or disable click mask to close vue-easy-lightbox.
dblclickDisabled (dblclick-closable)BooleanfalseEnable or disable double-click on img to zoom in/out.
teleportstring | Element-Specify the mount node for vue-easy-lightbox.
swipeTolerance (swipe-tolerance)Number50Specify the number of pixel you have to swipe.
zoomScaleNumber0.12Specify the step between zoom levels.
maxZoomNumber3Specify the maximum level of zoom scale.
minZoomNumber0.1Specify the minimum level of zoom scale.
rtlBooleanfalsesupport RTL (right to left) languages

Reference: Teleportopen in new window

Event

NameDescriptionReturn Value
hideWhen you click modal mask or close Btn, component will emit this event-
on-errorImage loading errorevent (event.target is not the image to be displayed)
on-prev /
on-prev-click
Emit when prev btn is clicked or when the user swiped right(oldIndex, newIndex)
on-next /
on-next-click
Emit when next btn is clicked or when the user swiped left(oldIndex, newIndex)
on-index-changeEmit when imgs's index is changed(oldIndex, newIndex)
on-rotateEmit when image rotatedeg: number (clockwise angle deg)

Slot

Slot NameSlot PropsSlot Props TypeDescription
prev-btnprevFunctionShow the prev img
next-btnnextFunctionShow the next img
close-btncloseFunctionClose modal
toolbar toolbarMethods: { zoomIn, zoomOut, rotate(rotateLeft), rotateLeft, rotateRight } { Function }Zoom in, zoom out, rotate(rotateLeft), rotateLeft, rotateRight
loading--Loading icon
onerror--Error Placeholder