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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:35:33