Vue使用swiper问题(5.2.0版本,避免踩坑)
短信预约 -IT技能 免费直播动态提醒
Vue使用Swiper看这一篇就够了
如果你还在用swiper@5.0以下的版本,如果你还在为坑多解决不了而烦恼,(ps:我已经踩了好多天的坑了)那么你不妨静下心来看完这篇博客,相信你会选择5.0版本的!!!
满足以下需求:
- 完成swiper动态异步数据下的slide重新渲染
- 解决loop:true设置时的事件丢失问题
- swiper鼠标移入/移出 暂停/开始轮播
- 单页面渲染多个swiper组件互不影响
- slide只有一页时停止自动滚动
- 自定义配置选项
一、下载指定版本swiper
npm i swiper@5.2.0
二、创建轮播图组件CarouselContainer.vue
详细解析在代码注释中
<template>
<div
class="CarouselContainer"
@mouseenter="stopAutoPlay"
@mouseleave="startAutoPlay"
>
<div ref="mySwiper" class="swiper-container" :id="currentIndex">
<div class="swiper-wrapper">
<div
class="swiper-slide my-swiper-slide"
v-for="(item, index) of slideList"
:key="index"
>
{{ item }}
</div>
</div>
<!-- 分页器 -->
<!-- <div class="swiper-pagination"></div> -->
<!--导航器-->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
</template>
<script>
import Swiper from "swiper";
import "swiper/css/swiper.css";
export default {
name: "CarouselContainer",
props: ["slideList", "currentIndex"],
data() {
return {
currentSwiper: null,
};
},
watch: {
//slide数据发生变化时,更新swiper
slideList: {
deep: true,
// eslint-disable-next-line
handler(nv, ov) {
console.log("数据更新了");
this.updateSwiper();
},
},
},
mounted() {
this.initSwiper();
},
methods: {
//鼠标移入暂停自动播放
stopAutoPlay() {
this.currentSwiper.autoplay.stop();
},
//鼠标移出开始自动播放
startAutoPlay() {
this.currentSwiper.autoplay.start();
},
//初始化swiper
initSwiper() {
// eslint-disable-next-line
let vueComponent = this; //获取vue组件实例
//一个页面有多个swiper实例时,为了不互相影响,绑定容器用不同值或变量绑定
this.currentSwiper = new Swiper("#" + this.currentIndex, {
// 循环模式选项loop,默认为false,可动态设置,当slide只有一页时置为false,>1页时置为true
loop: true, // 循环模式选项
autoHeight: "true", //开启自适应高度,容器高度由slide高度决定
//分页器
// pagination: {
// el: '.swiper-pagination',
// clickable:true,//分页器按钮可点击
// },
//grabCursor: true, //小手掌抓取滑动
// direction: "vertical", // 纵向滚动,默认是横向滚动的
on: {
//此处this为swiper实例
//切换结束获取slide真实下标
slideChangeTransitionEnd: function () {
console.log(vueComponent.$props.currentIndex+"号swiper实例真实下标",this.realIndex)
},
//绑定点击事件,解决loop:true时事件丢失
// eslint-disable-next-line
click: function (event) {
console.log("你点击了"+vueComponent.$props.currentIndex+"号swiper组件")
},
},
//导航器
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
autoplay: {
//自动播放,不同版本配置方式不同
delay: 2000,
stopOnLastSlide: false,
disableOnInteraction: false, // 用户操作之后是否停止自动轮播默认true
},
slidesPerView: 1, //视口展示slide数1
slidesPerGroup: 1, //slide数1页一组
});
},
//销毁swiper
destroySwiper() {
try {
// 此处destroy(bool1,bool2)
// bool1代表是否销毁swiper实例
// bool2代表是否销毁swiper样式(导航器、分页器等)
this.currentSwiper.destroy(true, false);
} catch (e) {
console.log("删除轮播");
}
},
//更新swiper(先销毁 再 重新初始化swiper)
updateSwiper() {
this.destroySwiper();
this.$nextTick(() => {
this.initSwiper();
});
},
},
// 组件销毁之前 销毁 swiper 实例
beforeDestroy() {
this.destroySwiper();
},
};
</script>
<style scoped lang="scss">
.CarouselContainer {
width: 100%;
height: 100%;
background-color: gray;
}
.my-swiper-slide {
height: 300px;
background-color: pink;
}
.swiper-container {
width: 700px;
border: 1px solid red;
}
//
// ::v-deep(.swiper-pagination-bullet-active){
// background-color: #d5a72f !important;
// width: 20px;
// }
//
// ::v-deep(.swiper-pagination-bullet){
// background-color: #9624bf;
// opacity: 1;
// width: 20px;
// }
</style>
三、创建父组件Father.vue渲染多个swiper组件、模拟异步数据变化
<template>
<div class="father">
<!--传递不同的currentIndex 作为区分不同swiper组件的动态id-->
<CarouselContainer :slide-list="list" currentIndex="1"></CarouselContainer>
<CarouselContainer :slide-list="list" currentIndex="2"></CarouselContainer>
<button @click="changeData">更换数据喽</button>
</div>
</template>
<script>
import CarouselContainer from './components/CarouselContainer.vue'
export default {
components: {
CarouselContainer,
},
data(){
return{
list:['a','b','c']
}
},
methods: {
changeData(){
const swiperList = ['我是图片1','我是图片2','我是图片3'];
this.list = swiperList ;
}
}
}
</script>
<style scoped>
</style>
完成之后就可以在你的项目中看到效果啦,之后可以根据项目需求去改进…
修改
此处追加说明destroy()释放swiper实例的几种情况:
解决问题:内存增长
此处destroy(bool1,bool2)
- bool1代表是否销毁swiper实例
- bool2代表是否销毁swiper样式(导航器、分页器等)
情景一:如果只更新swiper里面的数据,destroy(true,false)
情景二:如果要销毁(跳转路由销毁组件,遍历重新new一个swiper实例)swiper实例,destroy(true,true)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341