环境
版本:swiper 9.4.1
vue 3.2.13
问题
在使用swiper做轮播图时出现这个报错,发现当我们第一次进入时页面布局正常、各项功能都可以触发。
而当我们切换到其他页面再返回轮播图界面时,页面布局出现问题,并且交互都失效了
思考
此时打开控制台查看报错为:
查看对应源码,发现thumbs.swiper.el身上没有classList属性:
此时代码:
<template>
<template v-if="props.visible">
<div class="title">{{ props.title }}</div>
<div class="content" :class="props.myClass">
<swiper ref="mySwiper1" class="mySwiper1" :loop="true" :navigation="{
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}" :thumbs="{ swiper: thumbsSwiper }" :modules="modules">
<swiper-slide v-for="(item, index) in images" :key="index">
<img class="pic" :src="item.url" />
<div class="mask">
<div class="left">{{ item.title }}</div>
<div class="right"><span>{{ index + 1 }}</span>/{{ images.length }}</div>
</div>
</swiper-slide>
</swiper>
<div class="swiper-button-next" :class="props.myClass"></div>
<div class="swiper-button-prev" :class="props.myClass"></div>
<swiper ref="mySwiper2" class="mySwiper2" @swiper="setThumbsSwiper" :loop="true" :spaceBetween="3"
:slidesPerView="5" :modules="modules">
<swiper-slide v-for="(item, index) in images" :key="index">
<img class="thumbsPic" :src="item.url" />
</swiper-slide>
</swiper>
</div>
</template>
</template>
<script setup>
import { ref, defineProps, onBeforeUnmount } from 'vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/swiper-bundle.css';
import { FreeMode, Navigation, Thumbs } from 'swiper';
const modules = [FreeMode, Navigation, Thumbs];
const props = defineProps({
myClass: {
type: String,
default: 'day',
},
title: {
type: String,
default: '',
},
data: {
type: Object,
default: {},
},
visible: {
type: Boolean,
default: false,
},
});
const images = ref([
{ url: 'https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/baike/s=250/sign=206a1f4b4c086e066ea8384e32097b5a/eaf81a4c510fd9f94fd9d613252dd42a2934a4fa.jpg', title: '这是第一张' },
{ url: 'https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/baike/s=250/sign=206a1f4b4c086e066ea8384e32097b5a/eaf81a4c510fd9f94fd9d613252dd42a2934a4fa.jpg', title: '这是第二张' },
{ url: 'https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/baike/s=250/sign=206a1f4b4c086e066ea8384e32097b5a/eaf81a4c510fd9f94fd9d613252dd42a2934a4fa.jpg', title: '这是第三张' },
{ url: 'https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/baike/s=250/sign=206a1f4b4c086e066ea8384e32097b5a/eaf81a4c510fd9f94fd9d613252dd42a2934a4fa.jpg', title: '这是第四张' },
{ url: 'https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/baike/s=250/sign=206a1f4b4c086e066ea8384e32097b5a/eaf81a4c510fd9f94fd9d613252dd42a2934a4fa.jpg', title: '这是第五张' },
]);
const thumbsSwiper = ref(null);
const setThumbsSwiper = (swiper) => {
thumbsSwiper.value = swiper;
};
</script>
尝试每次切换时销毁swiper实例来避免错误,没有作用:
const mySwiper1 = ref(null);
const mySwiper2 = ref(null);
onBeforeUnmount(() => {
if (mySwiper1.value) {
mySwiper1.value.swiper.destroy();
}
if (mySwiper2.value) {
mySwiper2.value.swiper.destroy();
}
我们再看下为什么出错后,缩略图的布局会变化,可以看到出错时swiper-slide身上没有我们设置的宽高属性了:
正常:
报错时:
解决
想了一下,会不会是visible的锅呢?因为在picture组件内visible控制组件显示与隐藏,但是第一次初始化后的js部分还在缓存中,这个classList is undefined会是这个原因吗?
<Picture :visible="listData[selection].title == '施工图片'" :title="listData[selection].title"
:myClass="props.myClass" :data="listData[selection]"></Picture>
我们将控制显示影响的逻辑写在父组件内:
<Picture v-if="listData[selection].title == '施工图片'" :title="listData[selection].title"
:myClass="props.myClass" :data="listData[selection]"></Picture>
再次尝试触发bug,发现不会再报错了,切换后仍然可以和页面进行正常的交互。