在使用 Vue3 和 Vite 构建项目时,静态图片资源在开发和生产环境中通常能正常显示。然而,当尝试使用动态生成的图片资源(例如从数据库加载图片名称)时,会出现开发环境正常但生产环境无法显示图片的问题。本文将详细探讨该问题的表现、原因,并提供相应的解决方案。

问题描述

在 Vue3 结合 Vite 的项目里,静态图片源在开发和生产环境都能正常工作。但对于动态生成的图片源,情况则有所不同。

错误代码示例

<template>
<!--动态组合的 img src,生产环境会出问题 -->
<img :src="'/src/assets/images/' + menuItem.iconSource" />
</template>

现象

动态生成图片源在开发环境下能正常显示图片,但在 Vite 构建后的生产环境中,图片会出现 404 错误。这是因为 Vite 在构建时能正确处理静态图片的路径,但对于动态图片的组合路径却无法正确处理。

原因分析

Vite 在生产构建时不会处理动态组合的 img 标签的 src 路径,它将路径前缀视为常量。而实际的资源位置在构建后发生了变化(资源被放入 _assets 文件夹),这就导致了生产环境中图片出现 404 错误。另外,由于 Rollup 的限制,Vite 中的导入在以变量开头时存在限制。

解决方案

1. 静态 URL 方式

<template>
<img :src="imageUrl" alt="img" />
</template>
<script setup>
import imageUrl from "@/assets/images/logo.svg";
</script>

2. 动态 URL 与相对路径方式

<template>
<img :src="imageUrl" alt="img" />
</template>
<script setup>
const imageUrl = new URL(`./dir/${name}.png`, import.meta.url).href;
</script>

3. 动态 URL 与绝对路径,使用计算属性方式

<template>
<img :src="imageUrl" />
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({ name: String });
const imageUrl = computed(() => new URL(`@/assets/images/${props.name}.png`, import.meta.url).href);
</script>

4. 动态 URL 与绝对路径(替换 @/ 为 /src)方式

<template>
<img :src="imageUrl" alt="img" />
</template>
<script setup>
const imageUrl = new URL("/src/assets/images/logo.svg", import.meta.url);
</script>

另一个使用计算属性处理动态路径的示例

var imagePath = computed(() => {
switch (condition.value) {
case 1:
const imgUrl = new URL("../assets/1.jpg", import.meta.url);
return imgUrl;
break;
case 2:
const imgUrl2 = new URL("../assets/2.jpg", import.meta.url);
return imgUrl2;
break;
case 3:
const imgUrl3 = new URL("../assets/3.jpg", import.meta.url);
return imgUrl3;
break;
}
});

总结

在 Vue3 Vite 项目中处理动态图片源时,要注意 Vite 构建对静态和动态路径处理的差异。可以根据具体需求选择合适的解决方案,如使用静态 URL、动态 URL 结合相对或绝对路径,以及利用计算属性来处理动态路径,从而避免生产环境中图片出现 404 错误的问题。