You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:45:32