vue中动态引入图片

分析

很多时间,不管是vue2,还是vue3开发中都会遇到,动态渲染图片的功能,但是为什么我们直接将图片的路径直接赋值给变量的时候,图片渲染不出来,而通过require引入加载图片后却能正常渲染呢?主要原因在于webpack或vite编译的问题。(以下代码为vue3,vue2一样)

一般情况下,直接在src属性输入图片的路径,就能渲染出图片,如下

js 复制代码
<img src="./assets/img.jpeg" />

如果动态加载,就得动态绑定src属性,如下,

js 复制代码
<img :src="img1" />
<script setup>
import {ref} from "vue";
let img1 = ref('./assets/img.jpeg');
</script>

但是这样动态绑定src属性,是渲染不来图片,我们可以两者最终编译出来的html。

普通

动态加载

可以看出普通加载的图片会被编译成/img/img.13eb2ff7.jpeg这种路径,而动态加载的还是原始路径,这是因为webpack或vite,会将代码编译,最终在内容内构造出一个类似于打包后的dist文件,而就会将普通方式图片路径编译转化成dist文件夹下img文件夹下的资源。可以打包一下这时的代码。

可以看出图片资源被打包放在了img文件夹下,所有没有编译过的图片路径是访问不到的,这也是动态直接加载图片路径渲染不出来的原因。

但是有一点,在public文件夹下的图片,不管是webpack还是vite都不会进行编译,在该文件夹下的路径得是一个绝对路径,所以不管是普通引用还是动态加载图片都不会有问题的。

解决

1、vue2

在vue2中因为是通过webpack进行打包编译的,所以可以用require以模块的方式引入图片,webpack会将require引入的模块进行打包编译。

js 复制代码
const img = require('路径');

2、vue3

在vue3中是通过vite进行打包编译的,而require是webpack中函数,所以在vue3中不能,而vite官网给出了替代方法new URL。

js 复制代码
const imgUrl = new URL('./img.png', import.meta.url).href
document.getElementById('hero-img').src = imgUrl

import.meta.url 是一个 ESM 的原生功能,会暴露当前模块的 URL。

3、通用方法 import

不管是vue2还是vue3都可以通过import。

js 复制代码
import img from '路径';
注意

1、不管是webpack还是vite在图片大小一定范围内,两者都会把图片编译成base64形式,目的是较少HTTP请求,优化性能。webpack默认的图片打包规则,设置 type: 'asset',默认的,对于小于8k的图片,会将图片转成base64直接插入图片。

对于webpack可以在vue.config.js文件中进行设置,如下

js 复制代码
module.exports = {
    // 使用configureWebpack对象,下面可以直接按照webpack中的写法进行编写
    // 编写的内容,最终会被webpack-merge插件合并到webpack.config.js主配置文件中
  configureWebpack: { 
    module: {
      rules: [
        {
          test: /\.(png|jpe?g|gif|webp|avif)(\?.*)?$/,
          type: 'asset',
          parser: {
            dataUrlCondition: {
             // 这里我将默认的大小限制改成6k。
              // 当图片小于6k时候,使用base64引入图片;大于6k时,打包到dist目录下再进行引入
              maxSize: 1024 * 6
            }
          }
        }
      ]
    }
  }
}

在vite中在vite.config.js文件中进行设置,如下

js 复制代码
import { defineConfig } from "vite";

export default defineConfig({
  build: {
    // 10kb以下,转Base64
    assetsInlineLimit: 1024 * 10,
  },
});

2、public下的资源一定要绝对路径,虽然public文件不会被编译,但是src下的文件都会被编译。由于引入的是public下的资源,不会走require,会直接返回代码中的定义的文件地址,该地址无法在编译后的文件目录(dist目录)下找到对应的文件,会导致引入资源失败。

相关推荐
写代码的【黑咖啡】几秒前
Python中的文件操作详解
java·前端·python
Moment3 分钟前
一文搞懂 Tailwind CSS v4 主题变量映射背后的原理
前端·javascript·面试
我命由我123455 分钟前
JavaScript WebGL - WebGL 引入(获取绘图上下文、获取最大支持纹理尺寸)
开发语言·前端·javascript·学习·ecmascript·学习方法·webgl
辛-夷7 分钟前
2025年高频面试题整理(vue系列一)
前端·javascript·vue.js·前端框架
GISer_Jing7 分钟前
ByteDance AI战略:前端生态的颠覆者
前端·人工智能·aigc
大布布将军20 分钟前
⚡️ 性能加速器:利用 Redis 实现接口高性能缓存
前端·数据库·经验分享·redis·程序人生·缓存·node.js
Change!!22 分钟前
uniapp写的h5,怎么根据页面详情,设置不同的标题
前端·uni-app·标题
浅箬23 分钟前
uniapp 打包之后出现shadow-grey.png去除
前端·uni-app
梵得儿SHI27 分钟前
(第五篇)Spring AI 核心技术攻坚:流式响应与前端集成实现【打字机】效果
前端·webflux·springai·流式响应技术·低延迟ai交互·reactive编程原理·streamapi设计
鹏多多29 分钟前
一文搞懂柯里化:函数式编程技巧的解析和实践案例
前端·javascript·vue.js