在使用 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 错误的问题。