图片组件
图片组件展示
景色图片均通过 AI 生成
<PicViewer
title="图片组件展示"
src="/assets/components/scenery-1.jpg"
></PicViewer>
vite 对图片加载引用的介绍
首先 vite
在图片资源的处理上有一些不同于 webpack
,在 webpack
中常用的 require
在 vite
中不存在。
所以在这里简单介绍一下 vite 图片资源引用的问题。
首先图片资源的引用有相对路径
和绝对路径
之分,还有打包前
和打包后
增加文件指纹
之分。
路径问题先上一些图片位置图
以下是图片资源引用的情况
第一种 - 静态引入
使用地址是 public 文件夹(静态资源路径/根地址路径)下的文件,结果
主要代码
- 优点 开发生产环境都可以使用
- 缺点 但是不是相对路径不能让图片文件放到随意文件夹
- 缺点 而且没有图片指纹容易在更新文件时候导致资源不加载最新文件
因为直接使用静态资源路径,就等于直接访问图片,不经过打包所以不出问题
调用代码展示
<template>
<PicViewer title="静态资源路径" src="/assets/components/scenery-2.jpg" alt="根地址路径"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// 静态资源路径
</script>
第二种 - 相对路径
直接使用相对路径
- 缺点 开发生产图片都不展示,不可用
直接使用相对路径,组件
声明位置
和文档展示位置
不同,(受资源位置限制太大)
所以相对路径拿不到相应的文件所以展示不了
调用代码展示
<template>
<PicViewer title="最简单的相对路径" src="./assets/scenery-1.jpg"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// 最简单的相对路径
</script>
第三种 - new URL(静态)
new URL 引入,new URL 是 vite 提供的静态资源引用方法
主要代码
const imageUrl = new URL("./assets/scenery-1.jpg", import.meta.url).href;
- 缺点 开发环境没问题,生产环境刷新页面之后丢失
- 优点 可以放在任意文件夹
- 缺点 但是在加载的时候 必须显示的使用 new URL 引入资源 有点蠢
new URL(静态) 引入 会动态解析资源映射关系所以可以使用
调用代码展示
<template>
<PicViewer title="new URL(静态) 引入" :src="imageUrl"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// new URL(静态) 引入
const imageUrl = new URL("./assets/scenery-1.jpg", import.meta.url).href;
</script>
第四种 - new URL(动态)
new URL 引入,new URL 是 vite 提供的静态资源引用方法
主要代码
const newURLAll = import.meta.glob([
"./assets/*.jpg",
"./assets/*.png",
"./assets/*.gif",
]);
const imageMap: Map<string, string> = new Map();
for (const path in newURLAll) {
// `${path}` 这里是动态的
imageMap.set(path, new URL(`${path}`, import.meta.url).href);
}
- 缺点 开发可以,但是生产不行
- 优点 可以放在任意文件夹
- 小优点 在加载的时候 可以使用循环方式引入图片资源
new URL(动态) 引入 使用变量来控制图片加载,vite 将不解析。
在生产构建时,Vite 才会进行必要的转换保证 URL 在打包和资源哈希后仍指向正确的地址。然而,这个 URL 字符串必须是静态的,这样才好分析。否则代码将被原样保留、因而在 build.target 不支持 import.meta.url 时会导致运行时错误。
调用代码展示
<template>
<PicViewer title="new URL(动态) 引入" :src="imageMap.get(`./assets/scenery-2.jpg`)"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// new URL(动态) 引入
const newURLAll = import.meta.glob(["./assets/scenery-2.jpg"]);
const imageMap: Map<string, string> = new Map();
for (const path in newURLAll) {
// `${path}` 这里是动态的
imageMap.set(path, new URL(`${path}`, import.meta.url).href);
}
</script>
第五种 - imageUrl 方法
imageUrl 方法 通过一个方法传值来进行图片调用 使用的还是 new URL 方法但是转换成半静态了
主要代码
const imageUrl = (url: string) => {
// `./assets/${url}` 这个在vite的理解中是静态的
const obj = new URL(`./assets/${url}`, import.meta.url);
return obj.pathname;
};
- 缺点 开发环境没问题,生产环境刷新页面之后丢失
- 优点 可以放在任意文件夹
- 优点 在加载的时候 只需要传一个文件名 但是限制了当前路径的
assets
文件夹
new URL 在
./assets/${url}
代码中被理解成静态代码,所以进行资源映射处理。
调用代码展示
<template>
<PicViewer title="imgUrl方法" :src="imageUrl('scenery-3.jpg')"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// imageUrl 方法
const imageUrl = (url: string) => {
// `./assets/${url}` 这个在vite的理解中是静态的
const obj = new URL(`./assets/${url}`, import.meta.url);
return obj.pathname;
};
</script>
第六种 - import
import 引入
- 优点 开发生产都可以使用图片,没问题
- 优点 可以放在任意文件夹
- 缺点 但是在加载的时候 必须显示的使用 import 引入资源 有点蠢
import 引入 会动态解析资源映射关系所以可以使用
调用代码展示
<template>
<PicViewer title="import引入" :src="image"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// import引入
import image from "./assets/scenery-4.jpg";
</script>
第七种 - import.meta.glob
import.meta.glob 引入
- 优点 开发生产都可以使用图片,没问题
- 优点 可以放在任意文件夹
- 优点 在加载的时候 可以使用一个导入方法加载完所有图片
import.meta.glob(["./assets/*.jpg", "./assets/*.png", "./assets/*.gif"], {
eager: true,
import: "default",
});
该语句是 vite 的资源引入语句 import.meta.glob
["./assets/*.jpg", "./assets/*.png","./assets/*.gif"]
: 匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunkeager: true
: 直接引入所有的模块import: "default"
: import 为 default 可以加载默认导出
调用代码展示
<template>
<PicViewer title="import.meta.glob 引入" :src="importMetaGlob[`./assets/scenery-5.jpg`]"></PicViewer>
</template>
<script lang="ts" setup>
import PicViewer from "./index.vue";
// import.meta.glob 引入
const importMetaGlob: Record<string, string> = import.meta.glob(
["./assets/scenery-5.jpg"],
{
eager: true,
import: "default",
}
);
</script>
总结
在 vite 静态资源引用中 单个文件引用使用 import 是最方便的,多个文件引用的话推荐使用 import.meta.glob 方法