Swiper is familiar to anyone who has done swiper. This is a very powerful picture rotation plug-in, itself without any third-party library dependence, plug and play. The API documentation is clear, so it’s easy to get started. However, even the best plug-ins can be annoying, and of course, today’s discussion is not about the plug-ins themselves, but the developers are using them in the usual way, and there are inexplicable problems.
The reason:
When using swiper, dom binding events cannot be triggered when loop: True is set.
Environment:
- Vuejs 2.5.16
- Swiper 4.3.3
- Vue – awesome – swiper 3.1.3
Mining pit
Here’s how I solved the problem step by step. Only the key code snippets are posted here.
First edition:
The most common way to do this is to bind the Click event to the DOM. However, there are two disadvantages:
- Click events sometimes go unanswered, and they always do
- Clicking on the title below does not trigger the click event because there is no binding
The HTML code
<div class="banner" v-if="bannerList.length">
<swiper :options="swiperOption" ref="mySwiper">
<swiper-slide
v-for="(banner, index) in bannerList"
:key="banner.id"
@click.native="handleClickSlide(index)">
<div class="banner-item">
<img :src="banner.imgUrl" alt="news">
<p>{{banner.title}}</p>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>Copy the code
Js code
new Vue({
el: '#app',
data: function () {
return{swiperOption: {width: window.innerWidth, autoplay: {delay: 3000}, loop:true, // loop scrolling pagination: {//'.swiper-pagination'
},
preventLinksPropagation: false// prevent click events from bubbling}, bannerList: [{id:'1',
title: 'World Cup opener - Supernova 1 goal 2 assists Russia 5-0 Saudi Griezmann announces his move to Atletico Madrid',
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/AYes-hcyszrz3457297.jpg'
},
{
id: '2',
title: 'Full marks for appearance level! 'Beautiful women' on World Cup Day,
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/H3Wz-hcyszrz4804003.jpg'
},
{
id: '3',
title: 'Carnage' in World Cup history,
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/FNuk-hcyszrz4805039.jpg'}]}}, methods: {handleClickSlide(index) {console.log();'handleClickSlide current index', index); }}});Copy the code
Improved second edition:
The above two problems have been solved, but there are also the following problems
- The usual activeIndex (used to identify the number of images currently clicked), but the console output is out of order
- The activeIndex value is also distorted when toggling left and right
The HTML code
<div class="banner" v-if="bannerList.length">
<swiper :options="swiperOption" ref="mySwiper" @click.native="handleClickSlide">
<swiper-slide
v-for="(banner, index) in bannerList"
:key="banner.id">
<div class="banner-item">
<img :src="banner.imgUrl" alt="news">
<p>{{banner.title}}</p>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>Copy the code
Js code
new Vue({
el: '#app',
data: function () {
return{swiperOption: {width: window.innerWidth, autoplay: {delay: 3000}, loop:true, // loop scrolling pagination: {//'.swiper-pagination'
},
preventLinksPropagation: false// prevent click events from bubbling}, bannerList: [{id:'1',
title: 'World Cup opener - Supernova 1 goal 2 assists Russia 5-0 Saudi Griezmann announces his move to Atletico Madrid',
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/AYes-hcyszrz3457297.jpg'
},
{
id: '2',
title: 'Full marks for appearance level! 'Beautiful women' on World Cup Day,
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/H3Wz-hcyszrz4804003.jpg'
},
{
id: '3',
title: 'Carnage' in World Cup history,
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/FNuk-hcyszrz4805039.jpg'
}
]
}
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper; ActiveIndex = 1; activeIndex = 1; activeIndex = 0; // After a loop, click on the first image and the activeIndex output from the console changes to 4...handleClickSlideConst {activeIndex} = this.swiper &&this.swiper; const {activeIndex} = this.swiper &&this.swiper; console.log('handleClickSlide current index', activeIndex); }}});Copy the code
The final version
Swiper’s powerful API documentation addresses several of these issues. The key point is:
- when
loop
Set totrue
Can’t be used againactiveIndex
orclickedIndex
. Can only useRealIndex.The index of the active block, andactiveIndex
The difference is that in loop mode, noCopy the blockCount the number of. - Click events cannot be bound to
dom
on
However, if you are not careful, new pits can appear (as indicated in the code).
The HTML code
<div class="banner" v-if="bannerList.length">
<swiper :options="swiperOption" ref="mySwiper">
<swiper-slide
v-for="(banner, index) in bannerList"
:key="banner.id">
<div class="banner-item">
<img :src="banner.imgUrl" alt="news">
<p>{{banner.title}}</p>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>Copy the code
Js code
let vm = null;
new Vue({
el: '#app',
data: function () {
return{swiperOption: {width: window.innerWidth, autoplay: {delay: 3000}, loop:true, // loop scrolling pagination: {//'.swiper-pagination'
},
on: {
click: function() {// There is a pit // Note that this refers to the swpier instance, not the current vue, so use vm to call methods // console.log(this); // Swiper -> Swiper // Index of active blocks. Unlike activeIndex, the number of copied blocks is not counted in loop mode. const realIndex = this.realIndex; vm.handleClickSlide(realIndex); } }, preventLinksPropagation:false// prevent click events from bubbling}, bannerList: [{id:'1',
title: 'World Cup opener - Supernova 1 goal 2 assists Russia 5-0 Saudi Griezmann announces his move to Atletico Madrid',
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/AYes-hcyszrz3457297.jpg'
},
{
id: '2',
title: 'Full marks for appearance level! 'Beautiful women' on World Cup Day,
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/H3Wz-hcyszrz4804003.jpg'
},
{
id: '3',
title: 'Carnage' in World Cup history,
imgUrl: 'http://n.sinaimg.cn/sports/180/w640h340/20180615/FNuk-hcyszrz4805039.jpg'
}
]
}
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper; }},created() {
vm = this;
},
methods: {
handleClickSlide(index) {
console.log('handleClickSlide current index', index); }}});Copy the code
Hope this can help encountered this problem small partners, I wish you no more bugs in life.