Nuxt 3:如何在构建时读取/public下的图片文件路径?
问题:Nuxt 3构建时生成图片路径数组替代API读取
我的Nuxt 3项目中,/public/images目录下存放着大量分散在多个子目录的图片。为制作画廊页面,我需要读取所有图片的文件路径来渲染<img>标签,不想硬编码路径。目前是通过API端点实现该功能,代码如下:
import { readdir, stat } from "node:fs"; import { join } from "node:path"; async function read(path, callback) { let images = []; readdir(path, (err, files) => { if (err) { throw err; } let i = 0; (function next() { if (i === files.length) { return callback(images); } const file = join(path, files[i++]); stat(file, (err, stats) => { if (err) { throw err; } if (stats.isDirectory()) { read(file, (value) => { images = images.concat(value); next(); }); } else { images.push(file); next(); } }); })(); }); } export default defineEventHandler(async (_event) => { return await new Promise((resolve, reject) => { try { read("./public/images/blog", (value) => { resolve(value.map((value) => value.substring(6))); }); } catch (error) { reject(error); } }); });
我希望改为在构建时生成包含所有图片路径的数组,了解到可以通过生命周期钩子实现,但看不懂框架文档,求指引方向。
解决方案
1. 用nitro:build:before构建钩子(生产环境推荐)
这个钩子在Nuxt打包启动时执行,属于构建阶段逻辑,能一次性生成所有图片路径,无需运行时再读取文件,效率更高。
在项目根目录的nuxt.config.ts中添加以下代码:
import { defineNuxtConfig } from 'nuxt/config' import { readdir } from 'node:fs/promises' import { join } from 'node:path' // 递归遍历目录,过滤图片并返回public相对路径 async function getImagePaths(dir: string): Promise<string[]> { const entries = await readdir(dir, { withFileTypes: true }) let paths: string[] = [] for (const entry of entries) { const fullPath = join(dir, entry.name) if (entry.isDirectory()) { paths = [...paths, ...await getImagePaths(fullPath)] } else { // 按需筛选图片格式,可自行添加/修改后缀 const ext = entry.name.toLowerCase().slice(-4) if (['.jpg', '.jpeg', '.png', '.webp'].includes(ext)) { // 转换为public下的访问路径,比如/images/blog/photo.jpg paths.push(fullPath.replace('./public', '')) } } } return paths } export default defineNuxtConfig({ hooks: { async 'nitro:build:before'(nitro) { const imagePaths = await getImagePaths('./public/images/blog') // 将路径数组注入到公共运行时配置,页面可直接获取 nitro.options.runtimeConfig.public.imagePaths = imagePaths } } })
2. 在画廊页面使用路径数组
在你的画廊页面(比如pages/gallery.vue)中,直接通过useRuntimeConfig获取路径数组渲染图片:
<template> <div class="gallery-grid"> <img v-for="path in imagePaths" :key="path" :src="path" alt="Gallery image" class="gallery-item" /> </div> </template> <script setup> const { imagePaths } = useRuntimeConfig().public </script>
3. 开发阶段实时更新(可选)
如果开发时需要新增图片后自动更新路径,可配合app:created钩子(仅在开发模式启用,避免生产环境重复执行):
// 在nuxt.config.ts的hooks中追加 async 'app:created'(nuxtApp) { if (process.dev) { const imagePaths = await getImagePaths('./public/images/blog') nuxtApp.provide('imagePaths', imagePaths) } }
页面中获取方式改为:
<script setup> const imagePaths = useNuxtApp().$imagePaths </script>
内容的提问来源于stack exchange,提问作者muell
相关产品推荐
相关产品推荐

