Nuxt 3:如何程序化访问/public目录下的文件?
Nuxt3 实现/public目录图片图库(程序化获取文件)
方案一:服务端实时读取文件系统(适合动态场景)
通过创建Server API读取/public目录下的图片,支持指定子目录,运行时可实时获取最新文件。
步骤1:创建Server API路由
新建server/api/images/[dir].ts文件:
import { readdirSync, statSync } from 'fs' import { join } from 'path' export default defineEventHandler((event) => { // 获取路由参数中的子目录名,默认空(即public根目录) const targetDir = getRouterParam(event, 'dir') || '' const publicDirPath = join(process.cwd(), 'public', targetDir) // 定义需要匹配的图片格式 const validImageExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp'] // 递归遍历目录,收集图片路径 function collectImages(currentPath: string): string[] { let imagePaths: string[] = [] const files = readdirSync(currentPath) for (const file of files) { const fullFilePath = join(currentPath, file) const fileStats = statSync(fullFilePath) if (fileStats.isDirectory()) { // 递归处理子目录 imagePaths = [...imagePaths, ...collectImages(fullFilePath)] } else { // 检查文件后缀是否为图片格式 const fileExt = file.toLowerCase().slice(-4) if (validImageExts.includes(fileExt)) { // 转换为浏览器可访问的相对路径 const browserPath = fullFilePath.replace(join(process.cwd(), 'public'), '') imagePaths.push(browserPath) } } } return imagePaths } try { const images = collectImages(publicDirPath) return { images } } catch (err) { return { error: '目标目录不存在或无读取权限' } } })
步骤2:在页面组件中调用API
<script setup> // 调用API,指定子目录(比如public/gallery就传'gallery',空则为根目录) const { data: imageResp } = await useFetch('/api/images/gallery') const images = imageResp?.value?.images || [] </script> <template> <div class="image-gallery"> <img v-for="imgPath in images" :key="imgPath" :src="imgPath" alt="Gallery image" class="gallery-item" /> </div> </template> <style scoped> .image-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; padding: 1rem; } .gallery-item { width: 100%; height: 180px; object-fit: cover; border-radius: 4px; } </style>
方案二:Vite Glob导入(适合静态站点生成)
如果项目是静态生成(SSG),可直接用Vite的glob功能在构建时收集所有图片路径,无需运行时读取文件系统。
<script setup> // 匹配public/gallery下的所有图片,**表示递归子目录,可修改路径和格式 const imageAssets = import.meta.glob( '/public/gallery/**/*.{jpg,jpeg,png,gif,webp}', { eager: true, as: 'url' } ) // 将模块对象转换为路径数组 const images = Object.values(imageAssets) </script> <template> <div class="image-gallery"> <img v-for="imgUrl in images" :key="imgUrl" :src="imgUrl" alt="Gallery image" class="gallery-item" /> </div> </template> <style scoped> .image-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; padding: 1rem; } .gallery-item { width: 100%; height: 180px; object-fit: cover; border-radius: 4px; } </style>
注意事项
- 模板中的
:scr是笔误,需修正为:src - 方案一支持运行时动态更新图片,适合需要频繁新增图片的场景;方案二是构建时静态收集,适合不需要动态更新的静态站点
- 可根据需求调整图片格式的匹配规则,或添加更多图片类型
内容的提问来源于stack exchange,提问作者muell
相关产品推荐
相关产品推荐

