vue 实现图库功能
Vue 实现图库功能
基础项目搭建
使用 Vue CLI 或 Vite 创建项目,安装必要依赖如 vue-router 和图片处理库(如 v-viewer 或自定义组件)。
npm create vue@latest vue-gallery
cd vue-gallery
npm install v-viewer vue-lazyload
图片数据管理
通过数组管理图片数据,包含 id、src、thumbnail 和 description 等字段。数据可存储在 Vuex/Pinia 或组件局部状态中。
// 示例数据
const galleryImages = ref([
{
id: 1,
src: 'full-size-1.jpg',
thumbnail: 'thumb-1.jpg',
title: 'Mountain View'
},
// 更多图片...
]);
图片懒加载
使用 vue-lazyload 优化性能,避免一次性加载所有图片。
// main.js 配置
import VueLazyload from 'vue-lazyload';
app.use(VueLazyload, {
preLoad: 1.3,
loading: 'placeholder.png'
});
<!-- 组件中使用 -->
<img v-lazy="image.thumbnail" :alt="image.title">
图片预览功能
集成 v-viewer 实现点击缩略图查看大图的功能,支持缩放和滑动浏览。
// 安装配置
import Viewer from 'v-viewer';
import 'viewerjs/dist/viewer.css';
app.use(Viewer);
<template>
<div class="gallery">
<img
v-for="img in images"
:src="img.thumbnail"
@click="showGallery(index)"
:key="img.id">
</div>
</template>
<script setup>
const showGallery = (index) => {
const viewer = new Viewer(document.querySelector('.gallery'), {
initialViewIndex: index
});
viewer.show();
};
</script>
分类与过滤
添加分类筛选功能,通过计算属性动态过滤图片。
const activeCategory = ref('all');
const categories = ['all', 'nature', 'urban'];
const filteredImages = computed(() => {
return activeCategory.value === 'all'
? galleryImages.value
: galleryImages.value.filter(img => img.category === activeCategory.value);
});
响应式布局
使用 CSS Grid 或 Flexbox 实现自适应网格布局,结合媒体查询适配不同屏幕尺寸。
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}
@media (max-width: 768px) {
.gallery {
grid-template-columns: repeat(2, 1fr);
}
}
上传功能(可选)
通过 <input type="file"> 和 FileReader API 实现本地图片上传。
<input type="file" @change="handleUpload" multiple accept="image/*">
const handleUpload = (e) => {
const files = e.target.files;
Array.from(files).forEach(file => {
const reader = new FileReader();
reader.onload = (event) => {
galleryImages.value.push({
id: Date.now(),
src: event.target.result,
thumbnail: event.target.result
});
};
reader.readAsDataURL(file);
});
};
性能优化
- 使用 WebP 格式压缩图片
- 实现虚拟滚动(如
vue-virtual-scroller)处理大量图片 - 服务端分页加载(结合 API 分页参数)
// 分页示例
const page = ref(1);
const loadMore = async () => {
const res = await fetch(`/api/images?page=${page.value}`);
const newImages = await res.json();
galleryImages.value.push(...newImages);
page.value++;
};
完整组件示例
整合上述功能的单文件组件示例:
<template>
<div>
<div class="filters">
<button
v-for="cat in categories"
@click="activeCategory = cat"
:class="{ active: activeCategory === cat }">
{{ cat }}
</button>
</div>
<div class="gallery" ref="gallery">
<img
v-for="(img, idx) in filteredImages"
v-lazy="img.thumbnail"
@click="openViewer(idx)"
:key="img.id"
:alt="img.title">
</div>
<input type="file" @change="handleUpload" multiple accept="image/*">
</div>
</template>
<script setup>
// 逻辑代码...
</script>
<style scoped>
/* 样式代码... */
</style>






