在 Vue 项目中使用 npm Swiper 组件,在测试时发现在某些情况下绑定的 click 事件不起效。因为在点击 banner 时要做一些判断,比如是否登录,是否实名认证等,所以必须解决这一问题。
在 swiper 组件启用了 loop 循环模式时,会在原本 slide 前后复制若干个slide(默认一个)并在合适的时候切换,让 Swiper 看起来是循环的。
例如我们有 3 张 Banner,查看代码会发现,loop 模式的 swiper 会在第 1 个 slide 的前面复制一个 3,在 3 个的后面复制了一个 1,这样就可以实现循环的效果了。
但是问题来了,如果给 swiper 中的 slide 绑定了click事件,调用了某个方法的话,复制出来的这两个 slide 并不会把事件也复制过来。
也就是说点击复制出来的这两个 slide 是没办法调用我们的方法的,根本没有任何反应,无法实现页面跳转。
我查了一下 Swiper 的代码,swiper 有一个 realIndex
属性,代表 slide 真实下标,我们可以通过下标来判断验证条件和跳转的页面。
写一个简单的 swiper :
<!--banner Swiper轮播-->
<swiper class="index-banner" :options="swiperOption" @click.native="bannerSwiperClick()" ref="mySwiper">
<swiper-slide v-for="(item,index) in bannerSwiperImg" :key="index">
<img width="100%" :src="item" alt="">
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
JS 部分:
data: function () {
return {
bannerSwiperImg: [
"/static/img/ind-banner-1.png",
"/static/img/ind-banner-2.png",
"/static/img/ind-banner-3.png",
],
swiperOption: {
loop: true,
pagination: {
el:'.swiper-pagination',
type:'bullets',
clickable:true,
},
},
};
},
methods: {
bannerSwiperClick(){
let that = this,
ind = this.$refs.mySwiper.swiper.realIndex //获取下标
if (ind < 2){//如果不是3
if (!isLoggedIn()) {//判断未登录
window.location = '/Login?St=1';//跳登录
} else{//已登录
if (isRealName() !== '1') {//判断是否实名
this.showModal();//未实名弹窗
} else {
window.location = AIMS_URL;
}
}
} else {
window.location = '/';
}
},
},
这样就可以正常执行判断条件进行正常跳转了。使用组件虽然很方便,但有些时候还是很坑的。
说一下这里的 ref :
ref 被用来给 DOM 元素或子组件注册引用信息。引用信息会根据父组件的 $refs
对象进行注册。如果在普通的 DOM 元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例。
@click.native :
给 Vue 组件绑定事件时候,必须加上 native
,否则会认为监听的是来自 Item 组件自定义的事件
等同于在子组件中:子组件内部处理 click 事件然后向外发送 click 事件:$emit("click".fn)