在vue中使用swiper,关于在组件中的$refs下的各种属性 undefined 或者 not defined 的解决
一、背景swiper的内容是被封装在一个组件中,数据需要从父组件传递过来二、官方代码<template><div class="thumb-example"><!-- swiper1 --><swiper class="swiper gallery-top" :options="swiperOptionTop" ref="swiperTop"><
·
一、背景
swiper的内容是被封装在一个组件中,数据需要从父组件传递过来
二、官方代码
<template>
<div class="thumb-example">
<!-- swiper1 -->
<swiper class="swiper gallery-top" :options="swiperOptionTop" ref="swiperTop">
<swiper-slide class="slide-1"></swiper-slide>
<swiper-slide class="slide-2"></swiper-slide>
<swiper-slide class="slide-3"></swiper-slide>
<swiper-slide class="slide-4"></swiper-slide>
<swiper-slide class="slide-5"></swiper-slide>
<div class="swiper-button-next swiper-button-white" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-white" slot="button-prev"></div>
</swiper>
<!-- swiper2 Thumbs -->
<swiper class="swiper gallery-thumbs" :options="swiperOptionThumbs" ref="swiperThumbs">
<swiper-slide class="slide-1"></swiper-slide>
<swiper-slide class="slide-2"></swiper-slide>
<swiper-slide class="slide-3"></swiper-slide>
<swiper-slide class="slide-4"></swiper-slide>
<swiper-slide class="slide-5"></swiper-slide>
</swiper>
</div>
</template>
<script>
import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'
export default {
name: 'swiper-example-thumbs-gallery',
title: 'Thumbs gallery with Two-way control',
components: {
Swiper,
SwiperSlide
},
data() {
return {
swiperOptionTop: {
loop: true,
loopedSlides: 5, // looped slides should be the same
spaceBetween: 10,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}
},
swiperOptionThumbs: {
loop: true,
loopedSlides: 5, // looped slides should be the same
spaceBetween: 10,
centeredSlides: true,
slidesPerView: 'auto',
touchRatio: 0.2,
slideToClickedSlide: true
}
}
},
mounted() {
this.$nextTick(() => {
const swiperTop = this.$refs.swiperTop.$swiper
const swiperThumbs = this.$refs.swiperThumbs.$swiper
swiperTop.controller.control = swiperThumbs
swiperThumbs.controller.control = swiperTop
})
}
}
</script>
<style lang="scss" scoped>
.thumb-example {
height: 480px;
background-color: $black;
}
.swiper {
.swiper-slide {
background-size: cover;
background-position: center;
&.slide-1 {
background-image:url('/images/example/1.jpg');
}
&.slide-2 {
background-image:url('/images/example/2.jpg');
}
&.slide-3 {
background-image:url('/images/example/4.jpg');
}
&.slide-4 {
background-image:url('/images/example/5.jpg');
}
&.slide-5 {
background-image:url('/images/example/6.jpg');
}
}
&.gallery-top {
height: 80%;
width: 100%;
}
&.gallery-thumbs {
height: 20%;
box-sizing: border-box;
padding: $gap 0;
}
&.gallery-thumbs .swiper-slide {
width: 25%;
height: 100%;
opacity: 0.4;
}
&.gallery-thumbs .swiper-slide-active {
opacity: 1;
}
}
</style>
三、我的代码
先说一下我的代码的结构以及出现问题的原因所在,原因在于ref的渲染时间
其实官方文档里说的很清楚,ref的渲染时间是个很重要的讯息。下面是官网原话:
然后我又在其他博主那里看到了一点:
$refs定位不到的主要原因是因为v-if、v-for、v-show
这些语句如果依赖父组件传来的参数的话,该该参数是在mounted()阶段子还没获取得到
如果想要真正地在DOM加载完成后拿到数据,就需要调用VUE的全局api : this.$nextTick(() => {})
这里都能看到与官网给的解决方法是一样的,
但是忘了一点,我们的数据是动态的从父组件传递过来的,所以我们需要在watch中监听传递的数据的变化,再在watch中进行 this.$nextTick(() => {}) 的操作,而不是在mounted中进行。
下面是我的代码片段:
watch: {
swiperInfo: function(newVal, oldVal) {
var _this = this;
_this.propSwiperInfo = newVal; //newVal即是speedInfo
//如果$refs在绑定在v-if v-for v-show这些语句上,
//如果依赖父组件传来的参数的话,该参数是在mounted()阶段时候,是还没获取得到的,
//如果想要真正地在DOM加载完成后拿到数据,
//就需要调用VUE的全局api : this.$nextTick(() => {})
this.$nextTick(() => {
let swiperTop = _this.$refs.swiperTop.$swiper
let swiperThumbs = _this.$refs.swiperThumbs.$swiper
swiperTop.controller.control = swiperThumbs
swiperThumbs.controller.control = swiperTop
})
},
deep: true,
immediate: true
}
这个swiperInfo 就是父组件传递的props,这个propSwiperInfo,就是自定义的这个组件内的数据,我们在渲染数据的时候,直接绑定propSwiperInfo就可以,不要绑定swiperInfo,不然会有报错。
操作都很简单,其实就是原理与基础不熟悉,导致这个问题被困扰了很久。
更多推荐
已为社区贡献1条内容
所有评论(0)