VistaView provides official Vue 3 bindings with both a declarative component and a composable.
The VistaView component provides a declarative way to create image galleries. Any additional HTML attributes (e.g., class, style, data-*, aria-*) passed to the component are forwarded to the root <div>.
<script setup>
import { VistaView } from 'vistaview/vue';
import 'vistaview/style.css';
</script>
<template>
<VistaView>
<a href="/images/photo1-full.jpg">
<img src="/images/photo1-thumb.jpg" alt="Photo 1" />
</a>
<a href="/images/photo2-full.jpg">
<img src="/images/photo2-thumb.jpg" alt="Photo 2" />
</a>
</VistaView>
</template>
Note: The selector prop defaults to "> a", so you can omit it when your gallery contains direct <a> children.
We expose both the imperative API and the root DOM element on the component ref. Use a typed component ref to access vistaView (API) and container (DOM):
<script setup lang="ts">
import { ref } from 'vue';
import { VistaView } from 'vistaview/vue';
import type { VistaComponentRef } from 'vistaview/vue';
import 'vistaview/style.css';
const compRef = ref<VistaComponentRef>(null);
const openGallery = () => {
compRef.value?.vistaView?.open(0);
console.log(compRef.value?.container);
};
</script>
<template>
<VistaView ref="compRef">
<a href="/images/full.jpg">
<img src="/images/thumb.jpg" alt="Photo" />
</a>
</VistaView>
<button @click="openGallery">Open Gallery</button>
</template>
Note: compRef.value?.vistaView gives the API and compRef.value?.container gives the root DOM element.
<script setup>
import { VistaView } from 'vistaview/vue';
import type { VistaOpt } from 'vistaview';
import 'vistaview/style.css';
// Define options outside component to prevent recreation on every render
const options: VistaOpt = {
maxZoomLevel: 3,
preloads: 2,
animationDurationBase: 400,
onOpen: (vistaView) => console.log('Gallery opened'),
onClose: (vistaView) => console.log('Gallery closed'),
};
</script>
<template>
<!-- selector defaults to '> a' -->
<VistaView :options="options">
<a href="/images/photo1-full.jpg">
<img src="/images/photo1-thumb.jpg" alt="Photo 1" />
</a>
<a href="/images/photo2-full.jpg">
<img src="/images/photo2-thumb.jpg" alt="Photo 2" />
</a>
</VistaView>
</template>
Use the useVistaView composable for more control:
<script setup>
import { useVistaView } from 'vistaview/vue';
import 'vistaview/style.css';
const vista = useVistaView({
elements: '#gallery > a',
});
</script>
<template>
<div id="gallery">
<a href="/images/full.jpg">
<img src="/images/thumb.jpg" alt="Photo" />
</a>
</div>
<button @click="vista.open(0)">Open Gallery</button>
<button @click="vista.next()">Next</button>
<button @click="vista.prev()">Previous</button>
</template>
Extensions can be used with both the component and composable approaches.
<script setup>
import { VistaView } from 'vistaview/vue';
import { download } from 'vistaview/extensions/download';
import 'vistaview/style.css';
const options = {
controls: {
topRight: ['zoomIn', 'zoomOut', 'download', 'close'],
},
extensions: [download()],
};
</script>
<template>
<VistaView :options="options">
<a href="/images/photo1.jpg">
<img src="/images/photo1-thumb.jpg" alt="Photo 1" />
</a>
</VistaView>
</template>
<script setup>
import { useVistaView } from 'vistaview/vue';
import { download } from 'vistaview/extensions/download';
import 'vistaview/style.css';
const vista = useVistaView({
elements: '#gallery > a',
controls: {
topRight: ['zoomIn', 'zoomOut', 'download', 'close'],
},
extensions: [download()],
});
</script>
<template>
<div id="gallery">
<a href="/images/photo1.jpg">
<img src="/images/photo1-thumb.jpg" alt="Photo 1" />
</a>
</div>
</template>
If you prefer the Options API:
<script>
import { vistaView } from 'vistaview';
import 'vistaview/style.css';
export default {
data() {
return {
vista: null,
};
},
mounted() {
this.vista = vistaView({
elements: '#gallery > a',
});
},
beforeUnmount() {
this.vista?.destroy();
},
};
</script>
<template>
<div id="gallery">
<a href="/images/photo1.jpg">
<img src="/images/photo1-thumb.jpg" alt="Photo 1" />
</a>
</div>
</template>