Reputation: 665
I created a gallery using Vue, Nuxt.
The full code of my gallery you can find on GitHub,
and you can see a live demo here vue gallery demo
Most of the logic is in the vue-lighbox component.
<script>
export default {
props: {
thumbnails: {
type: Array,
required: true,
},
images: {
type: Array,
required: true,
},
thumbnailPath: {
type: String,
required: true,
},
imagePath: {
type: String,
required: true,
},
},
data() {
return {
visible: false,
currentImage: 0,
}
},
methods: {
Toggle(index) {
this.currentImage = index
this.visible = !this.visible
},
Next() {
if (this.currentImage < this.images.length - 1) {
this.currentImage++
} else {
this.currentImage = 0
}
},
Prev() {
if (this.currentImage > 0) {
this.currentImage--
} else {
this.currentImage = this.images.length - 1
}
},
},
}
</script>
<template>
<div class="thumb_container">
<div v-for="(thumbnail, index) in thumbnails" :key="thumbnail" class="thumbnail" @click="Toggle(index)">
<img :src="thumbnailPath + thumbnail" />
<div class="plus">
<i class="icon icon-plus" />
</div>
<div class="color-overlay"></div>
</div>
<div v-if="visible" class="lightbox">
<i class="icon-cancel" @click="Toggle()" />
<i class="icon-left" @click="Prev()" />
<i class="icon-right" @click="Next()" />
<img :key="currentImage" :src="imagePath + [currentImage + 1] +'.jpg'" />
</div>
</div>
</template>
A quick break down of my component:
I have small thumbnail images and big images. The thumbnail images are displayed with for loop. Whenever I click at some of the thumbnails the corresponding big image appears.
The gallery is working fine as intended, however, I have a problem with loading the photos from user experience aspect. So I need to implement a loading spinner while the big image is loading.
I really don't know the right approach to this. Does someone have an example to share or some hint to give me?
How can I check when a fallowing image is loaded?
Upvotes: 0
Views: 572
Reputation: 1677
You can use vue's v-on:load
directive to determine whether to show an image or a spinner. In my app I've made this into a custom component:
<template>
<div>
<img :src="src"
:alt="alt"
@load="onLoaded"
@error="onError"
v-show="loaded && !error"
key="image"/>
<spinner-component v-show="loaded == false || error"/>
</div>
</template>
export default {
mounted() {
},
data() {
return {
loaded: false,
error: false
}
},
props: {
src: {
type: String
},
alt: {},
width: {},
height: {}
},
computed: {
style({ width, height }) {
return {
width: width,
height: height,
objectFit: "contain"
}
}
},
methods: {
onLoaded() {
this.loaded = true;
},
onError() {
this.error = true;
}
}
}
Upvotes: 2