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目录)下找到对应的文件,会导致引入资源失败。

相关推荐
许___3 分钟前
Vue使用原生方式把视频当作背景
前端·javascript·vue.js
萌萌哒草头将军24 分钟前
尤雨溪强烈推荐的这个库你一定要知道 ⚡️⚡️⚡️
前端·vue.js·vite
2401_8784545328 分钟前
Vue 核心特性详解:计算属性、监听属性与事件交互实战指南
前端·vue.js·交互
GISer_Jing1 小时前
Next.js数据获取演进史
java·开发语言·javascript
1024小神1 小时前
uniapp+vue3+vite+ts+xr-frame实现ar+vr渲染踩坑记
前端
测试界清流1 小时前
基于pytest的接口测试
前端·servlet
知识分享小能手2 小时前
微信小程序入门学习教程,从入门到精通,自定义组件与第三方 UI 组件库(以 Vant Weapp 为例) (16)
前端·学习·ui·微信小程序·小程序·vue·编程
trsoliu2 小时前
多仓库 Workspace 协作机制完整方案
前端
啦工作呢2 小时前
数据可视化 ECharts
前端·信息可视化·echarts
NoneSL2 小时前
Uniapp UTS插件开发实战:引入第三方SDK
前端·uni-app