解决Vue 3 + Vite 4 动态导入图片报错undefined问题

Situation&Task

列表渲染,需要根据列表每行item的type字段导入不同icon并渲染到页面

Action

一开始想要使用require动态导入图片的方式加载image

<div
    :style="{
        backgroundImage: `url(
        ${require(`./assets/${getFileIcon(item)}`)}
    )`}">
</div>
...
getFileIcon(item) {
    return 'image.png';
},

但是会报错

“require is not defined”

因为 Vite 是一个基于现代浏览器原生ES模块的开发服务器,并不支持使用 CommonJS(require导入)模块语法

所以我们需要另辟蹊径:使用 vite 提供的静态资源载入方法

import.meta.url是一个 ESM 的原生功能,会暴露当前模块的 URL。将它与原生的URL 构造器组合使用,在一个 JavaScript 模块中,通过相对路径我们就能得到一个被完整解析的静态资源 URL,同时也可以通过字符串模板支持动态 URL

  1. import.meta元属性将特定上下文的元数据暴露给 JavaScript 模块。它包含了这个模块的信息,例如这个模块的 URL。
  2. URL接口用于解析,构造,规范化和编码URL。将 URL 指定为字符串或提供相对 URL 和基本 URL 来创建新的 URL 对象。然后,你可以轻松读取 URL 的已解析组成部分或对 URL 进行更改。

其中 URL 的 href 属性包含我们需要的数据:即完整 URL 字符串

<img
    :src="getFileIconUrl(item)"
    alt=""
/>
...
const getImageUrl = (item) => {
    let name = name='test1.png';
    if (name) {
        return new URL(`./assets/${name}`, import.meta.url).href;
    }
    return new URL(`./assets/test2.png`, import.meta.url).href;
};

这样会出现新的问题

渲染出来的img标签内容不对,我们看到,引入的图片资源变成了undefined,继续排查原因

<img src="http://localhost:9999/undefined />

我们将模板字面量移动到一个变量中,然后再将路径和资源名拼接一起返回就可以解决这个问题

const getImageUrl = (item) => {
    let name = name='test1.png';
    if (name) {
        const path = new URL('./assets/', import.meta.url);
        return `${path}/${name}`;
    }
    return new URL(`./assets/test2.png`, import.meta.url).href;
};

Result

这样我们的图片就能顺利渲染出来了

Vite开发的项目中无法使用CommonJS模块语法,需要使用Vite本身提供的静态资源引入方式实现我们的需求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值