vue3和vite的环境下 img和el-image 加载本地图片的问题

3 阅读2分钟

下面是 @ 的配置

// vite.config.js
return defineConfig({
    base: './',
    resolve: {
     alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
     },
    },

下面是加载本地图片,猜一猜哪个能正确加载出来

<el-image class="img" src="@/assets/image/icon-g-zh.png" fit="cover" />
<el-image class="img" src="@assets/image/icon-g-zh.png" fit="cover" />
<el-image class="img" src="../../assets/image/icon-g-zh.png" fit="cover" />
<el-image class="img" :src="scImage['zh']" fit="cover" />

<img class="img" src="@/assets/image/icon-g-zh.png" fit="cover" />
<img class="img" src="../../assets/image/icon-g-zh.png" fit="cover" />
<img class="img" :src="`../../assets/image/icon-g-${zh}.png`" fit="cover" />
<img class="img" :src="`@/assets/image/icon-g-${zh}.png`" fit="cover" />

<div class="img_2"></div>

.img_2 {
   width: 35px;
   height: 20px;
   margin-top: 10px;
   background-image: url(../../assets/image/icon-g-zh.png);
   background-color: blue;
}

image.png

(1)Vite 使用 ES 模块,而 require() 是 CommonJS 模块的特性不能使用。

(2)使用 import 语法加载图片, el-image 和 img 都可以加载

(3)静态路径,img 可以加载 @路径 和 相对路径, el-image都不可

(4)动态路径, img el-image 都不可



  • 下面看看 动态路径 编译后的结果
let zh = 'zh'  

<img class="img" :src="`../../assets/image/icon-g-${zh}.png`" fit="cover" />
<img class="img" :src="`@/assets/image/icon-g-${zh}.png`" fit="cover" />
编译后在 浏览器中看是下面两条
<img class="img" src="../../assets/image/icon-g-zh.png" fit="cover">
<img class="img" src="@/assets/image/icon-g-zh.png" fit="cover">


<img class="img" src="@/assets/image/icon-g-zh.png" fit="cover" />
<img class="img" src="../../assets/image/icon-g-zh.png" fit="cover" />
编译后在 浏览器中看是下面两条
<img class="img" src="/src/assets/image/icon-g-zh.png" fit="cover">
<img class="img" src="/src/assets/image/icon-g-zh.png" fit="cover">

Vite 只解析了一次,比如第一条,动态的路径先转为 ../../assets/image/icon-g-zh.png 本来还有解析一次的。

chatgpt 的解释, 不一定正确

**Vite 资源处理机制**:在 Vue 3 项目中(尤其是使用 Vite 时),
模板中的相对路径不能直接解析到 `src/assets` 下的文件。
这是因为 Vite 处理资源文件的方式不同,
只有通过 JavaScript 的 `import` 才能让打包工具正确处理资源的路径和哈希

解决方案:

方法 1:使用 import 引入图片

// 在 ./src/assets/image/index.js 下导出同级目录下的图片

export { default as by } from './icon-g-by.png'
export { default as de } from './icon-g-de.png'
export { default as en } from './icon-g-en.png'
export { default as fr } from './icon-g-fr.png'
export { default as jp } from './icon-g-jp.png'
export { default as kr } from './icon-g-kr.png'
export { default as nl } from './icon-g-nl.png'
export { default as ru } from './icon-g-ru.png'
export { default as th } from './icon-g-th.png'
export { default as zh } from './icon-g-zh.png'

vue中导入使用

import * as scImage from "../../assets/image";


<img
 v-else
 class="image-container"
 :src="scImage[scope.row.lang]"
 fit="cover"
 :alt="item" />

方法2. 动态路径拼接 + import.meta.url 未验证

<script setup> 
function getImageSrc(zh) { 
    return new URL(`../../assets/image/icon-g-${zh}.png`, import.meta.url).href 
} 
</script>

方法 3:使用 public 目录

<img class="img" src="/images/icon-g-zh.png" fit="cover" />

这些问题 webpack 好像没有, 很久没用了有点忘记

vite 的网址:cn.vite.dev/guide/