这几天公司有个小需求在h5中左右滑动卡片,数据有点多,还有些卡片中的点击事件,遇到几个坑,记录一下!
直接上代码!大佬勿喷~
<swiper v-if="elements.length > 1 && swiperBool"
class="swiper gallery-top cardBox"
:options="swiperOptionTop"
@slideNextTransitionEnd="slideNextTransitionEnd"
@slidePrevTransitionEnd="slidePrevTransitionEnd"
ref="swiperRef">
<swiper-slide v-for="i in realRenderArr"
class="swiper-lazy"
:id="'lsjswiper_'+i.id"
:key="'swiper_'+i.id">
<DetailCard :data="i"
@showRecord="showRecord"
@showFullImg="showFullImg(i.elementUrl)"
@showMore="showMore"></DetailCard>
</swiper-slide>
</swiper>
data() {
return {
elements: [],
swiperOptionTop: {
slidesPerView: 1.28, // 设置slider容器能够同时显示的slides数量,可以是小数,设置为2时,如图所示,设置为3则会出现三张完整的active slide,如API的例子,即设置为偶数时会自动使两边的缩进,类似遮盖一半的效果
spaceBetween: 15,
centeredSlides: true, // 设定为true时,active slide会居中,而不是默认状态下的居左
slideToClickedSlide: true, // true:点击slide会过渡到这个slide,默认false
pagination: {
el: '.swiper-pagination',
clickable: true
},
lazy: false,
loop: true,
loopedSlides: 3, // looped slides should be the same
autoplay: false,
initialSlide: 2,
on: {
//----warning --- 被复制的swiper 点击事件无效
click: (event) => {
console.log(event);
if (event.target.id === 'recordTextId') {
this.showRecord();
} else if (event.target.id === 'elementUrlId') {
this.showFullImg(
this.elements[this.numIndex].elementUrl
);
}
}
}
},
};
},
computed: {
realRenderArr() {
let r = this.getcurrentRoundArr(this.numIndex, this.elements);
// console.log(r);
return r;
},
},
methods: {
getcurrentRoundArr(index, ele = []) {
if (ele.length < this.isVirfixNum) {
return ele;
} else {
let cur = index;
let next1 = index == ele.length - 1 ? 0 : index + 1;
let next2 = next1 == ele.length - 1 ? 0 : next1 + 1;
let pre1 = index == 0 ? ele.length - 1 : index - 1;
let pre2 = pre1 == 0 ? ele.length - 1 : pre1 - 1;
// let lastest1 = ele.length - 1;
// let lastest2 = ele.length - 2;
// let lastest3 = ele.length - 3;
return [
ele[pre2],
ele[pre1],
ele[cur],
ele[next1],
ele[next2]
// ele[lastest3],
// ele[lastest2],
// ele[lastest1]
];
}
},
}
参数说明:
elements:接口返回的数据
realRenderArr: 实际展示的数据源
DetailCard: 每个小卡片展示组件
大概思路:
因为数据量比较大,所以取了数据的当前展示的索引和前后各2个,这样渲染的dom也就是swiper-slide的数据就会急剧减少。
【其中也试过百度中的一些思路,比如把DetailCard替换成<div></div>,但是这样还是会卡,毕竟swiper-slide数量摆在那】
因为是无限循环模式(loop:true),swiper会复制你的首尾节点去保持它内部的循环逻辑,但是这也导致了另外一个问题,被复制的dom能够正常渲染,但是绑定的事件都不生效了,比如上述代码中DetailCard组件里的showRecord等事件。
事件失效解决方法:
调用option中的on.click事件,获取event,上述代码也有体现。