问题描述
- 在使用vite的vue3项目使用了动态访问静态资源,代码如下
- 即给swiper-slide盒子动态添加背景图片,动态渲染页面
<div class="main">
<div class="swiper-wrapper">
<Swiper
:modules="[Pagination, Navigation, Autoplay]"
:pagination="{ clickable: true }"
loop
:autoplay="{ delay: 3000 }"
:slides-per-view="1"
>
<Swiper-slide
class="swiper-slide"
v-for="item in slides"
:key="item.img"
:style="{ backgroundImage: `url(${item.img})` }"
>
</Swiper-slide>
</Swiper>
</div>
<div class="menu"></div>
</div>
问题表现
发现这个图片是加载不出来的,路径是没问题的
然后打包这个项目,发现打包出来的文件也没有存在在打包目录中
原因分析
- Vite 是一个在编译时运行的工具,因此它在构建过程中会静态地解析和处理资源。
- 如果在代码中使用动态绑定静态资源(如使用变量拼接路径或通过动态表达式导入资源),Vite 在编译时无法解析这些路径,因此这些资源不会被正确地识别、处理或打包。
- 只有显式的动态资源才会被认为是依赖,并在构建时处理
解决方案
1. 使用import方式导入图片
<script setup>
import { Swiper, SwiperSlide } from "swiper/vue";
import { Navigation, Pagination, Autoplay } from "swiper/modules";
import banner1 from "@/assets/swiper/banner_s3.jpg";
import banner2 from "@/assets/swiper/chequedeposit_s.jpg";
import banner3 from "@/assets/swiper/iGTB Mobile Token.jpg";
import banner4 from "@/assets/swiper/igtb_topbanner.jpg";
import banner5 from "@/assets/swiper/iGTBTopBanner_SC.jpg";
import banner6 from "@/assets/swiper/iGTB_banner_api.jpg";
const slides = [
{
img: banner1,
title: "1",
},
{
img: banner2,
title: "2",
},
{
img: banner3,
title: "3",
},
{
img: banner4,
title: "4",
},
{
img: banner5,
title: "5",
},
{
img: banner6,
title: "6",
},
];
</script>
<template>
<div class="main">
<div class="swiper-wrapper">
<Swiper
:modules="[Pagination, Navigation, Autoplay]"
:pagination="{ clickable: true }"
loop
:autoplay="{ delay: 3000 }"
:slides-per-view="1"
>
<Swiper-slide
class="swiper-slide"
v-for="item in slides"
:key="item.img"
:style="{ backgroundImage: `url(${item.img})` }"
>
</Swiper-slide>
</Swiper>
</div>
<div class="menu"></div>
</div>
</template>
2. 使用new URL方式加载图片
<script setup>
import { Swiper, SwiperSlide } from "swiper/vue";
import { Navigation, Pagination, Autoplay } from "swiper/modules";
const slides = [
{
img: new URL("@/assets/swiper/banner_s3.jpg", import.meta.url),
title: "1",
},
{
img: new URL("@/assets/swiper/chequedeposit_s.jpg", import.meta.url),
title: "2",
},
{
img: new URL("@/assets/swiper/iGTB Mobile Token.jpg", import.meta.url),
title: "3",
},
{
img: new URL("@/assets/swiper/igtb_topbanner.jpg", import.meta.url),
title: "4",
},
{
img: new URL("@/assets/swiper/iGTBTopBanner_SC.jpg", import.meta.url),
title: "5",
},
{
img: new URL("@/assets/swiper/iGTB_banner_api.jpg", import.meta.url),
title: "6",
},
];
</script>
<template>
<div class="main">
<div class="swiper-wrapper">
<Swiper
:modules="[Pagination, Navigation, Autoplay]"
:pagination="{ clickable: true }"
loop
:autoplay="{ delay: 3000 }"
:slides-per-view="1"
>
<Swiper-slide
class="swiper-slide"
v-for="item in slides"
:key="item.img"
:style="{ backgroundImage: `url(${item.img})` }"
>
</Swiper-slide>
</Swiper>
</div>
<div class="menu"></div>
</div>
</template>
3.public
直接将资源放在public里面
4.使用import()
import("@/assets/swiper/iGTB_banner_api.jpg").then((res) => {
console.log("res", res.default);
url.value = res.default;
});