Skip to content

Directive ​

Suitable for simple image browsing without complex customization, while also supporting images in dynamically rendered Markdown or HTML whose content is not known in advance. By default, it watches additions, removals and attribute changes of <img> elements inside the element the directive is bound to and automatically updates the gallery.

Playground ​

Playground

vue
<script>
import Vue from 'vue'
import VueViewer from 'v-viewer'
Vue.use(VueViewer)
const sourceImages = [
  '/images/photo-01.jpg',
  '/images/photo-02.jpg',
  '/images/photo-03.jpg',
  '/images/photo-04.jpg',
  '/images/photo-05.jpg',
  '/images/photo-06.jpg',
  '/images/photo-07.jpg',
  '/images/photo-08.jpg',
  '/images/photo-09.jpg',
  '/images/photo-10.jpg',
].map((original) => ({
  src: original.replace('/images/', '/images/thumbnails/'),
  'data-source': original,
}))
export default {
  data() {
    return {
      sourceImages,
      images: sourceImages.slice(0, 5),
      options: { toolbar: true, url: 'data-source' },
    }
  },

  methods: {
    add() {
      this.images.push(this.sourceImages[this.images.length])
    },
    remove() {
      this.images.pop()
    },
    show() {
      this.$refs.gallery.$viewer.show()
    },
    onViewed(event) {
      console.log(event.detail.index)
    },
  },
}
</script>

<template>
  <main class="viewer-example">
    <div class="controls">
      <button :disabled="images.length === sourceImages.length" @click="add">
        Add image
      </button>
      <button :disabled="images.length === 0" @click="remove">
        Remove image
      </button>
      <button class="open" :disabled="images.length === 0" @click="show()">
        Show viewer
      </button>
      <div class="toolbar" role="group" aria-label="Toggle toolbar">
        <span>Toggle toolbar</span>
        <button
          :aria-pressed="options.toolbar ? 'true' : 'false'"
          @click="options.toolbar = true"
        >
          On
        </button>
        <button
          :aria-pressed="options.toolbar ? 'false' : 'true'"
          @click="options.toolbar = false"
        >
          Off
        </button>
      </div>
    </div>
    <div ref="gallery" v-viewer="options" @viewed="onViewed" class="gallery">
      <img
        v-for="(image, index) in images"
        :key="image.src"
        :src="image.src"
        :data-source="image['data-source']"
        :alt="`Landscape ${index + 1}`"
      />
    </div>
  </main>
</template>

Rendered HTML works the same way:

vue
<article v-viewer v-html="html" />

Binding and modifiers ​

BindingDescription
v-viewer="options"Accepts Viewer.js options. Deep changes rebuild the instance.
v-viewer="{ observe: false }"Disable automatic image DOM updates.
v-viewer="{ observe: 100 }"Batch image DOM changes in a 100ms window; default true uses 50ms, 0 adds no batching delay.
v-viewer="{ rebuild: true }"Recreate the instance when images change; defaults to false and supports reactive changes.
.rebuildShorthand for rebuild: true.

rebuild in the binding takes precedence over .rebuild, including an explicit false. When omitted or undefined, the modifier applies.

By default, additions, removals and attribute changes of <img> elements inside the element the directive is bound to automatically update the gallery. Access the instance as element.$viewer. Unmounting disconnects the observer and destroys the instance.

See automatic updates with observe for values, update timing and usage guidance.

ts
import type { ViewerElement } from 'v-viewer'
const element = document.querySelector<ViewerElement>('#gallery')
element?.$viewer?.show()

Options ​

Pass these settings directly in the object bound to v-viewer="options". Deep changes rebuild the instance.

These match Viewer.js options. Each name links to its original documentation; available settings and defaults depend on the installed Viewer.js version.

PropTypePurpose
backdropboolean / stringControl the modal backdrop; static keeps clicks on it from closing the viewer.
buttonbooleanShow the button in the upper-right corner.
classNamestringAdd custom classes to the viewer root.
containerstring / ElementChoose the modal container using an element or CSS selector.
filterfunctionInclude images for which the filter returns true; exclude the others.
fullscreenboolean / FullscreenOptionsRequest browser fullscreen during playback, optionally with Fullscreen API settings.
focusbooleanFocus the active thumbnail on initialization; requires keyboard.
inheritedAttributesarrayChoose additional source-image attributes to copy; src and alt are always copied.
initialCoveragenumberSet the initial image coverage, greater than 0 and at most 1.
initialViewIndexnumberChoose the starting image index, also used when view() receives no index.
inlinebooleanDisplay the viewer inline when enabled, or in modal mode when disabled.
autoplaybooleanAdvance slides automatically during playback.
intervalnumberSet the delay between slides in milliseconds.
keyboardbooleanAllow keyboard controls.
loadingbooleanDisplay a loading indicator while fetching an image.
loopbooleanWrap image navigation between the first and last images.
magnifierboolean / objectShow a hover magnifier in fullscreen view, with configurable size, ratio and opacity; unavailable on touch screens.
maxZoomRationumber / functionLimit magnification with a ratio or a function of the image and its data.
minHeightnumberSet the minimum inline viewer height in pixels.
minWidthnumberSet the minimum inline viewer width in pixels.
minZoomRationumber / functionLimit reduction with a ratio or a function of the image and its data.
movablebooleanAllow image movement.
navbarboolean / number / string / objectConfigure thumbnail visibility, size and position, with further layout settings in object form.
navigationboolean / number / objectConfigure the side navigation buttons, including individual visibility and size.
preloadbooleanLoad adjacent images before they are viewed.
rotatablebooleanAllow image rotation.
rotateOnGesturebooleanRotate through gesture events, such as two-finger gestures in Mac Safari.
rotateOnTouchbooleanRotate with two fingers on a touch screen.
scalablebooleanAllow axis scaling, including horizontal and vertical flips.
slideOnTouchbooleanNavigate between images with touch swipes.
slideOnWheelboolean / stringNavigate with the wheel, optionally requiring modifier keys; applies over thumbnails or when wheel zoom does not handle the event.
titleboolean / number / function / arrayConfigure title visibility and content; the default uses alt or the filename from the URL.
toggleOnDblclickbooleanSwitch between natural and initial image sizes on double-click.
toolbarboolean / number / objectConfigure toolbar placement and button visibility, size and click behavior.
tooltipbooleanDisplay the current zoom percentage while zooming.
transitionboolean / objectEnable CSS transitions, or disable selected action transitions using an object.
urlstring / functionRead the full image URL from a named image attribute or a function result.
zIndexnumberSet the modal viewer’s CSS stacking order.
zIndexInlinenumberSet the inline viewer’s CSS stacking order.
zoomOnGesturebooleanZoom through gesture events, such as pinch gestures in Mac Safari.
zoomOnTouchbooleanZoom through dragging gestures on a touch screen.
zoomOnWheelboolean / stringZoom with the wheel, optionally requiring one or more modifier keys.
zoomRationumberSet the ratio increment for wheel zoom.
zoomablebooleanAllow image zooming.

Events ​

Viewer.js dispatches native DOM events on the HTML element bound to the directive. Listen using syntax such as @viewed. The handler receives the original event, with operation data in event.detail. Use @show.prevent to cancel opening.

vue
<div v-viewer="options" @viewed="onViewed">
  <img src="/images/photo-01.jpg" />
</div>
NameWhen it fires / useful data
readyThe viewer UI is initialized. In modal mode this can happen on the first opening.
show / shownBefore opening / after the opening transition completes in modal mode.
hide / hiddenBefore closing / after the closing transition completes in modal mode.
view / viewedBefore displaying an image / after it is displayed. detail.index is zero-based; image and originalImage identify the preview and source images.
move / movedBefore / after moving. detail.x, y, oldX and oldY describe the position change.
rotate / rotatedBefore / after rotation. detail.degree and oldDegree describe the angle change.
scale / scaledBefore / after scaling or flipping. detail.scaleX, scaleY, oldScaleX and oldScaleY describe the change.
zoom / zoomedBefore / after zooming. detail.ratio and oldRatio contain the zoom ratios.
play / stopBefore starting / stopping a slideshow.
playingBefore showing each slide during playback.

Callbacks ​

You can also set Viewer.js callbacks in options, using the names and parameters listed above:

js
const options = {
  viewed(event) {
    console.log(event.detail.index)
  },
}

When @viewed and options.viewed are both supplied, both run for the same event. Use either when they perform the same work.

Migrating from older versions ​

The .static modifier has been removed; replace it with { observe: false }.

Released under the MIT License.