文章目录
场景
官网:Swiper - 最现代的移动触控滑块 - Swiper 中文
最近用svelte写轮播图,用了Swiper组件。需求是:一共三张图,来回切,保持循环(1,2,3->2,3,1->3,1,2->1,2,3).
像这样:
版本:6.8.4和11.1.4
写一个博客记录一下学习过程和踩过的坑。
代码(6.8.4)
js:
初始化一个轮播图,有4个属性,分别表示:
- 容器内显示3个轮播图
- 选中的居中
- 循环
- 初始第2个居中(索引从0开始)
import Swiper from 'swiper/swiper-bundle';
import 'swiper/swiper-bundle.css';
import { onMount, afterUpdate } from 'svelte';
let swiperContainer, swiperInstance;
onMount(() => {
// 轮播图
swiperInstance = new Swiper('.swiper-container', {
slidesPerView: 3, //'auto'
centeredSlides: true,
loop: false,
initialSlide: 1,
});
})
// 在数据更新后要更新一下轮播图
afterUpdate(() => {
if (swiperInstance) {
swiperInstance.update();
}
});
html:
网络请求得到数据,原本使用循环渲染每一个slide,即3个。但是,这样会使得loop失效:使用loop的话(loop:true)要请求完图片才知道有多少个slide,会导致:一进页面不能立即显示轮播图。
我们期望一进页面就看到三个图(尽管没有图片,但有三个框)。
注意:这里我们
loop:true
,但是上面的js代码loop:false
,原因后面说。
因此我们写死三个div。
但是:loop:true
虽然会显示循环,但是效果不好,在循环的图active(选中居中)之前,它是没有图片渲染出来的。如:循3,1,2
的 循3 是空的,要把 循3 滑到中间,即 循2,循3,1
,循3 才会显示出图片,但是此时循2没有显示出图片。
解决方法:手动循环。div写死五张图,这样一进页面所有图都是渲染出来的。
<div bind:this={swiperContainer} class="swiper-container">
<div class="swiper-wrapper">
<!-- 手动添加第三张图,防止初次渲染不会复制出现空图 -->
<div class="swiper-slide">
<img class="cover" src={coverList[2]} alt="coverImage" />
</div>
<div class="swiper-slide">
<img class="cover" src={coverList[0]} alt="coverImage" />
</div>
<div class="swiper-slide">
<img class="cover" src={coverList[1]} alt="coverImage" />
</div>
<div class="swiper-slide">
<img class="cover" src={coverList[2]} alt="coverImage" />
</div>
<div class="swiper-slide">
<img class="cover" src={coverList[0]} alt="coverImage" />
</div>
</div>
</div>
手动实现滑动:
// 当滑动结束时,检查是否需要跳转到对应的复制图片,比loop配置好用
swiperInstance.on('slideChangeTransitionEnd', function () {
if (swiperInstance.activeIndex === 0) {
swiperInstance.slideTo(swiperInstance.slides.length - 2, 0, false); // 无动画地跳转到倒数第二张图片
} else if (
swiperInstance.activeIndex ===
swiperInstance.slides.length - 1
) {
swiperInstance.slideTo(1, 0, false); // 无动画地跳转到第二张图片
}
});
css:
注意要占满轮播图的容器空间,不然滑动时可能出现图片的偏移。
.swiper-slide
是每个slide的类,.swiper-slide-active
是选中居中的类,.swiper-slide-prev
是选中居中的前一个的类,.swiper-slide-next
是选中居中的后一个的类。
如果要样式穿透:
:global(.swiper-slide)
如果想防止循环的slide露出来(非页面的三个),可以将他设置为透明:opacity: 0;
,将active、prev、next设置为opacity: 1;
代码(11.1.4)
import Swiper from 'swiper';
import 'swiper/css';
import { onMount } from 'svelte';
onMounted(()=>{
// 轮播图
swiperInstance = new Swiper('.swiper', {
slidesPerView: 3, //'auto'
centeredSlides: true,
loop: true,
initialSlide: 0,
});
// 拿完数据后,前后滑动,为了显示全数据(不然左边没数据)
swiperInstance.slideNext(0);
swiperInstance.slidePrev(0);
})
样式基本没变。