swiper.js 是一款强大的插件,也是我最喜欢的开源插件之一。它能够轻松实现轮播、tab 标签以及各类风骚的页面滑动效果。css
我在本身的不少项目里都用到了 swiper,配合 vue 使用真的很是方便。不过近日遇到一个小坑,几番搜索和试验,才发现与 loop 特性有关。html
具体现象是,当 swiper 开启 loop 属性实现循环轮播,同时用 vue 的事件绑定语法为每一个轮播页绑定事件,当轮播到特定的页面时绑定的事件没法被正常监听。vue
例以下面的代码:node
<template> <div id="app"> <div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide" v-for="i in 2" :key="i" >Slide {{ i }}</div> </div> </div> </div> </template> <script> import Swiper from 'swiper' import 'swiper/css/swiper.css' export default { name: 'app', mounted () { const mySwiper = new Swiper('.swiper-container', { loop: true }) console.log(mySwiper) }, methods: { handleClick (i) { console.log(`click slide ${i}`) } } } </script>
这段代码实际上添加了两页轮番,loop = true 会实现循环轮播的效果。但实际使用过程当中发现,Slide1 上绑定的 click 事件监听,除了初始时第一次显示时能正常捕获外,当连续向左滚动以后显示的 Slide1 页上点击就没效果了。一样,向右滑动时,Slide2 上绑定的事件监听器也可能出现问题。app
打开调试控制台查看页面元素,发现除了实际添加的两页轮播对应的 slide 元素以外,左边多了一个复制的 Slide2 元素,而右边则多了一个复制的 Slide1。ide
原来 Swiper 是经过在实际轮播页先后复制若干个页面来实现 loop(首尾相连循环滚动)效果的,联想到前面提到的问题现象,立刻猜想是由于虽然复制了轮播页元素但 vue 所绑定的事件处理器却没有被复制。因而进一步查看了这个元素上绑定的事件监听器,果真如此。oop
找到的问题缘由,那也就有头绪了。Swiper.js 本身其实也提供了一套事件绑定机制,咱们只须要把原代码里 vue 指定绑定的事件监听器经过 Swiper 初始选项中绑定就行了。调整后的代码以下。spa
<template> <div id="app"> <div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide" v-for="i in 2" :key="i" :data-index="i" >Slide {{ i }}</div> </div> </div> </div> </template> <script> import Swiper from 'swiper' import 'swiper/css/swiper.css' export default { name: 'app', mounted () { const mySwiper = new Swiper('.swiper-container', { loop: true, on: { click: (e) => { const index = e.target.dataset.index console.log(`click slide ${index}`) } } }) console.log(mySwiper) } } </script>
再次试用点击事件,一切正常了。插件