下面给你一份最完整、最清晰、适合收藏的《Vue 前端动态导入文件之 import.meta.glob 导入图片详细过程》。
支持 Vue3 + Vite,并包含真实项目写法、踩坑说明、最佳实践。
🚀 一文完全搞懂 import.meta.glob 动态导入图片(Vue3 / Vite)
import.meta.glob 是 Vite 提供的强大功能,可用于动态批量导入文件,包括:
- 图片(PNG、JPG、SVG、GIF…)
- JSON
- Markdown
- 组件
- 任何静态资源
尤其适用于:
✔ 图片数量多
✔ 图片文件名动态
✔ 不想一张一张 import
✔ 需要根据用户选择动态加载
📌 1. 基础概念:什么是 import.meta.glob?
Vite 语法:
const modules = import.meta.glob('./assets/*.png');
返回:
{
'./assets/a.png': () => import('./assets/a.png'),
'./assets/b.png': () => import('./assets/b.png'),
...
}
👉 返回的是一个对象,value 是一个动态 import 函数。
你需要手动调用它才能获取图片的最终 URL。
📌 2. 正确用法:批量导入所有图片
示例目录结构:
src/
└─ assets/
├─ 1.png
├─ 2.png
├─ 3.png
Vue3 导入:
const images = import.meta.glob('@/assets/*.png', { eager: true });
👉 关键点:eager: true 会直接返回导入结果,而不是函数。
结果结构:
{
'/src/assets/1.png': { default: '/assets/1.abc123.png' },
'/src/assets/2.png': { default: '/assets/2.e2e90ac.png' }
}
获取图片 URL:
const imageUrls = Object.keys(images).map(key => images[key].default);
📌 imageUrls 就是你真正能放在 :src 中的图片 URL 列表。
📌 3. 在模板中使用图片
例如循环渲染图片:
<template>
<div v-for="(img, i) in imageUrls" :key="i">
<img :src="img" />
</div>
</template>
<script setup>
const images = import.meta.glob('@/assets/*.png', { eager: true });
const imageUrls = Object.keys(images).map(key => images[key].default);
</script>
📌 4. 按文件名动态选择图片(非常常用)
比如用户选择的图片编号是 3,希望加载 3.png。
动态匹配:
const modules = import.meta.glob('@/assets/*.png', { eager: true });
function getImage(name) {
for (const path in modules) {
if (path.includes(name)) {
return modules[path].default;
}
}
}
使用:
<img :src="getImage('3')" />
📌 5. 更优雅的方式:将文件名作为 key
const images = import.meta.glob('@/assets/*.png', { eager: true });
const map = {};
Object.entries(images).forEach(([path, mod]) => {
const fileName = path.split('/').pop();
map[fileName] = mod.default;
});
export default map;
使用:
<img :src="map['3.png']" />
📌 6. 也可以按目录递归导入
const images = import.meta.glob('@/assets/**', { eager: true });
匹配所有子目录。
📌 7. 动态 import(懒加载图片)
当 { eager: false } 或默认情况:
const modules = import.meta.glob('@/assets/*.png');
async function loadImage(name) {
for (const key in modules) {
if (key.includes(name)) {
const mod = await modules[key]();
return mod.default;
}
}
}
动态调用:
<img :src="img" v-if="img" />
<script setup>
const img = ref(null);
loadImage('2').then(res => img.value = res);
</script>
📌 8. import.meta.glob 导入图片常见坑
❌ 错误 1:路径必须是静态字符串,不支持变量
// ❌ 错误
import.meta.glob(`@/assets/${dir}/*.png`);
必须写成:
// ✔ 正确
import.meta.glob('@/assets/**/*.png');
❌ 错误 2:import.meta.glob 不支持 Webpack
只有 Vite 项目能用。
Vue2 + Webpack 的人要用 require.context()。
❌ 错误 3:直接放到 template 会报错
不能:
<img :src="import.meta.glob(...)" /> // ❌
必须放在 script 中生成 URL。
❌ 错误 4:public 文件夹不需要 glob
public 的资源直接使用:
/image/banner.png
不需要 import.meta.glob。
📌 9. 实战示例:动态主题、皮肤、卡片资源加载
常用于游戏、后台主题、模板系统:
const skins = import.meta.glob('@/skins/**/*.png', { eager: true });
const skinMap = {};
for (const key in skins) {
const fileName = key.slice(key.lastIndexOf('/') + 1);
skinMap[fileName] = skins[key].default;
}
根据用户选择:
<img :src="skinMap[user.skin + '.png']" />
📌 10. 最终总结:import.meta.glob 用来干什么?
| 功能 | 使用说明 |
|---|---|
| 批量导入图片 | ✔ 最常用 |
| 动态匹配并返回 URL | ✔ getImage(name) |
| 按需懒加载图片 | ✔ 动态 import |
| 渲染大量静态资源 | ✔ 比手动 import 快得多 |
| 生成“文件名 → URL”映射表 | ✔ 后台管理项目常用 |
| 自动化导入 JSON/Markdown/组件 | ✔ 文档系统常用 |
发表回复