vue实现画廊
Vue实现画廊功能
使用Vue实现画廊功能可以通过组件化开发结合第三方库或原生JavaScript实现。以下是两种常见方案:
基于vue-gallery组件
安装vue-gallery库:
npm install vue-gallery --save
基本实现代码:
<template>
<gallery :images="images" :index="index" @close="index = null"></gallery>
<div class="image" v-for="(image, imageIndex) in images" :key="imageIndex"
@click="index = imageIndex" :style="{ backgroundImage: 'url(' + image + ')' }"></div>
</template>
<script>
import VueGallery from 'vue-gallery';
export default {
components: {
'gallery': VueGallery
},
data() {
return {
images: [
'image1.jpg',
'image2.jpg',
'image3.jpg'
],
index: null
}
}
}
</script>
<style>
.image {
float: left;
width: 200px;
height: 200px;
margin: 5px;
cursor: pointer;
background-size: cover;
}
</style>
原生Vue实现方案
<template>
<div class="gallery">
<div class="thumbnails">
<img v-for="(img, idx) in images" :key="idx"
:src="img.thumbnail" @click="openLightbox(idx)">
</div>
<div class="lightbox" v-if="lightboxVisible" @click="closeLightbox">
<img :src="currentImage.full" class="lightbox-image">
<button @click.stop="prevImage">Previous</button>
<button @click.stop="nextImage">Next</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
images: [
{ thumbnail: 'thumb1.jpg', full: 'full1.jpg' },
{ thumbnail: 'thumb2.jpg', full: 'full2.jpg' }
],
currentIndex: 0,
lightboxVisible: false
}
},
computed: {
currentImage() {
return this.images[this.currentIndex]
}
},
methods: {
openLightbox(index) {
this.currentIndex = index
this.lightboxVisible = true
},
closeLightbox() {
this.lightboxVisible = false
},
prevImage() {
this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length
},
nextImage() {
this.currentIndex = (this.currentIndex + 1) % this.images.length
}
}
}
</script>
<style>
.thumbnails {
display: flex;
flex-wrap: wrap;
}
.thumbnails img {
width: 150px;
height: 150px;
object-fit: cover;
margin: 5px;
cursor: pointer;
}
.lightbox {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.8);
display: flex;
align-items: center;
justify-content: center;
}
.lightbox-image {
max-width: 80%;
max-height: 80%;
}
</style>
高级功能扩展
添加过渡动画
<transition name="fade">
<div class="lightbox" v-if="lightboxVisible">
<!-- 内容 -->
</div>
</transition>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
键盘导航支持
mounted() {
window.addEventListener('keydown', this.handleKeydown)
},
beforeDestroy() {
window.removeEventListener('keydown', this.handleKeydown)
},
methods: {
handleKeydown(e) {
if (this.lightboxVisible) {
if (e.key === 'ArrowLeft') this.prevImage()
if (e.key === 'ArrowRight') this.nextImage()
if (e.key === 'Escape') this.closeLightbox()
}
}
}
图片懒加载优化
使用vue-lazyload插件:
npm install vue-lazyload
实现代码:
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
preLoad: 1.3,
loading: 'loading.gif',
attempt: 1
})
// 模板中使用
<img v-lazy="img.thumbnail">
响应式设计建议
/* 响应式布局 */
.thumbnails {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 10px;
}
@media (max-width: 768px) {
.thumbnails {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
}






