vue2+webpack
在vue2中,可以使用 require 以模块的方式动态引入资源文件,webpack会将 require 引入的模块进行打包编译。
// 正常引入assets静态资源
<img width="16" src="@/assets/images/file.png" alt="描述性文本" />
如果图片无法显示,浏览器将会显示alt
属性中的文本,这有助于提高网站的可访问性。
require 动态引入
<img :src="require('@/assets/images' + item.icon.toLowerCase() + '.png')" alt="" />
<img :src="require(`@/assets/images/${icon}.${isPng ? 'png' : 'svg'}`)" alt="">
<img :src="imageSrc('icon)" alt="" />
imageSrc(imageName) {
return require(`@/assets/images/${imageName}.png`);
}
<img :src="urlPrefix() + '/images/demo.png" alt="" />
// 获取url前缀地址
urlPrefix() {
const origin = '';
return origin ? `${origin}/static` : '';
}
动态添加背景图片
在添加背景图片时,可以使用图片名称作为动态参数,提取公共方法完成样式处理。
<div :style="setStyle('imgName')">添加背景图片</div>
<div :style="setStyle(active === 'first' ? 'active_bg' : 'bg')"></div>
methods: {
setStyle(name) {
return `
background-image: url(${require(`@/assets/images/${name}.png`)});
background-size: 100% 100%;
`;
}
vue3+vite
vue2中可以使用require动态引入图片,但在开发vue3+vite项目的时候,使用require 会报错 require is not defind。因为require是webpack的方法,vite是不支持的。
import 引入(适用于单个资源文件)
import homeBg from 'src/assets/images/home/home_bg.png'
<img :src="homeBg" />
如果引用资源不多,也可以逐一引入使用
new URL() + import.meta.url(适用于多个资源文件)
(1)在src/util目录下创建一个utils.js文件
// 获取assets静态资源,动态传入文件路径
export const getAssetsFile = (url: string) => {
return new URL(`../assets/images/${url}`, import.meta.url).href;
};
(2)在vue文件中导入并使用
import { getAssetsFile } from 'src/util/utils';
<img class="bg-img" :src="getAssetsFile('bg.png')" alt="">
import.meta.glob (官方提供API)
(1) 指定具体文件夹路径,传入的变量为文件名、文件类型
export const getAssetsFile = (fileName: string, type = 'png') => {
const path = `/src/assets/images/${fileName}.${type}`;
const modules: Record<string, any> = import.meta.glob("@/assets/images/*.{png,svg,jpg,jpeg}", { eager: true });
if (modules[path]) return modules[path].default;
else {
// 地址错误
console.error("Error url is wrong path");
}
};
(2)动态设置文件路径,传入的变量为文件名、文件路径、文件类型
const getAssetsFile = (url: string, folder = null, type = 'png') => {
const path = folder ? `/src/assets/images/${folder}/${url}.${type}` : `/src/assets/images/${url}.${type}`;
const modules: Record<string, any> = import.meta.glob(`@/assets/images/**/*.{png,svg,jpg,jpeg}`, { eager: true });
if (modules[path]) return modules[path].default;
……
};
public+绝对路径
把所有静态资源放到public/
目录下,引用的资源路径改为绝对路径
并去掉public前缀。如:引入 public/static/home/首页.png,直接使用 /static/home/首页.png 即可。
原理:
在Vite中, / 开头的绝对路径默认可以访问到 public/ 目录下的内容,所以 /public/static/home/首页.png 和 /static/home/首页.png 都可以访问到本地资源。
但在打包时,Vite默认会原样保留绝对路径的引用地址,但不会保留public文件夹,即public下的static文件夹会被直接输出到dist/目录下,而没有public文件夹了。
所以虽然这两种都可以访问到本地资源,但是考虑到默认的打包处理方式,还是要去除掉/public前缀才能保证打包之后也可以正常引入静态资源。
背景图片引入
.bg-box{
background-image: url('../../assets/images/bg.png');
}
结束语
静态资源可以通过两种方式进行处理:
-
在 JavaScript
被导入
或在 template/CSS 中通过相对路径
被引用。这类引用会被 webpack 处理。 -
放置在
public
目录下或通过绝对路径
被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。
webpack或vite,将代码编译后最终会构造出一个类似于打包后的dist文件,会将普通方式图片路径编译转化成dist/img文件夹下的资源。所有没有编译过的图片路径是访问不到的,这也是动态直接加载图片路径渲染不出来的原因
在public文件夹下的图片,不管是webpack还是vite都不会进行编译,在该文件夹下的路径是一个绝对路径,所以不管是普通引用还是动态加载图片都不会有问题。