文章目录
- vue中图片不显示问题
- 静态资源
- URL 转换规则
- webpack 静态资源处理
- 图片不显示问题
- 问题描述
- 解决办法1:使用require引入
- require is not defined
- 解决办法2:使用import引入
- 解决办法3:将图片放进公共文件夹static或public
vue中图片不显示问题
静态资源
- 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理后再输出到打包后的文件。
- 放置在 public(static)目录下或通过绝对路径被引用。这类资源将会直接被拷贝到打包后的文件,而不会经过 webpack 的处理。
在config.js
的build.assetsPublicPath
和build.assetsSubDirectory
中设置
// config/index.js
module.exports = {// ...build: {assetsPublicPath: '/',assetsSubDirectory: 'static'}
}
URL 转换规则
- 如果URL是一个绝对路径
如/panda.png
,则该路径会被保留 - 如果URL以
.
开头,会被理解为相对路径,并基于目录结构进行解析。没有前缀的URL, 如assets/logo.png
将会被看成相对URL
,并且转换成./assets/logo.png
。例如,url(./image.png)
会被翻译为require('./image.png')
- 如果URL以
@
开头,也会作为一个模块请求被解析。Vue CLI 默认会设置一个指向 /src 的别名 @。(仅作用于模版中)
webpack 静态资源处理
在*.vue
组件中,所有的templates
和css
都会被vue-html-loader
和 css-loader
解析,寻找资源的URL
。
在JavaScript里获取资源路径
为了能让Webpack返回正确的资源路径,使用require('./relative/path/to/file.jpg')
,由file-loader
进行解析,然后返回处理过的URL
。
图片不显示问题
问题描述
直接传地址是可以正常显示的
<img src="./assets/tile.jpg" alt="">
但很多需求不允许直接传递。比如父组件往子组件传递图片地址等。然后发现使用变量传递字符串后图片不显示。
/* 错误写法 */
// js
const imgSrc = './assets/tile.jpg'//template
<img :src="imgSrc"></img>
原因
根据结果来看,相对地址没有被解析。在webpack
中会将图片来当做模块来用,因为是动态加载的,所以url-loader
将无法解析图片地址(被webpack
解析到的路径都会被解析为/static/img/[filename].png
)
解决办法1:使用require引入
正确的引入方法
使用require
引用后,由file-loader
进行解析,然后返回处理过的URL
。
const img_src = require('../../assets/images/panda.png');
console.log(img_src); // 打印 ./assets/images/panda-aad48f9a4cf0f953ccb4af0ad32bd3cc.png<img :src="imgSrc"></img>
使用require的错误引入方法
<img :src="require(imgSrc)"></img>
这里的错误原因理解的是动态绑定src
,img_src
被理解为变量,而require
没有被理解为变量。src
去读取img_src
变量的值,该变量的值就是一个字符串,所以最后显示的是字符串没有解析地址去获取图片。
require is not defined
vue3+typeScript
使用require
方法引入图片的时候会报错require is not defined
因为require
是webpack
提供的一种加载能力,但是vue3
项目时搭配vite
的,所以这里应该用vite
提供的静态资源载入方法,
vite官网的静态资源载入方法
import.meta.url
是一个 ESM 的原生功能,会暴露当前模块的 URL。与原生的 URL
构造器 组合使用,在一个 JavaScript
模块中,通过相对路径我们就能得到一个被完整解析的静态资源 URL
// js
const img_src = new URL("./assets/tile.jpg", import.meta.url).href
//img_src: http://127.0.0.1:5173/src/assets/tile.jpg
//import.meta.url: http://127.0.0.1:5173/src/App.vue?t=1706082462328
console.log(img_src,import.meta.url)//template
<img :src="img_src" alt="">
解决办法2:使用import引入
打印tile
的结果是/src/assets/tile.jpg
,import
引入后地址由相对路径变成了绝对路径,webpack
不会对绝对路径进行处理。
require是在运行时加载,import是编译时加载
// js
import tile from "./assets/tile.jpg";
console.log(tile)//template
<img :src="tile" alt="">
解决办法3:将图片放进公共文件夹static或public
1.将图片放进公共文件夹static或public
2.然后使用绝对路径引入