问题:在上一篇文章中写到了自己封装的一个tabBar的组件,以实现能够左右滑动的功能,我使用的是就是小程序里面自带的 swiper 组件来实现。但是经过测试发现了一个问题:当进入页面快速快速的滑动几次就会开始闪烁,页面自己就不停的左右滑动。

进行真机调试的时候, 通过控制台打印可以发现是 bindChange 绑定的方法重复执行了, 这时候我找到了官方文档的解释 跳转官方文档

swiper_01

这时候可以发现, 我确实是在 bindChange 绑定的方法里面使用了 setData() 这个方法, 来保证swiper组件的 current 属性与我们的 this.data.activeIndex 保持同步.

为什么要有 this.data.activeIndex 这个变量?是因为我们要获得当前的页数进行其他的操作。比如底部的 tab 就用到这个变量。但是这个变量必须在 bindChange 进行同步。

至此,我们的程序在快速滑动的时候是有问题的。不断触发setData()。此外,在官方的开发社区找到这么一条:

swiper_02

后来一想,在bindChange改变 swiper 的 current 是有问题的,那么,改变另外的变量呢?答案是没有问题的。

那么,解决办法就是在 data 里定义2个变量:

1
2
3
4
5
6
7
/**
* 组件的初始数据
*/
data: {
cur: 0, //改变当前索引
activeIndex: 0 //当前的索引
},

当前的页数用 activeIndex 来标记。swiper组件的current属性我们用变量cur。互不干扰。

当页面变化时,我们设置 activeIndex, 当我们需要改变页面时,我们设置cur

所以我将之前的代码做了一些修改, 问题就解决啦~~~~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<view class="tabview">
<view class="tabs {{position == 'top'?'top':'bottom'}}">
<block wx:for="{{tabs}}" wx:key="index">
<view class="tab-son {{activeIndex ==index?'active':''}}" data-index="{{index}}" bindtap='toggleTab'>
<image class='tab-icon' src='{{activeIndex ==index?item.selectedIcon:item.icon}}' mode='aspectFit'></image>
<view class='tab-text'>{{item.name}}</view>
</view>
</block>
</view>
<swiper current="{{cur}}" class="tab-swiper {{position == 'top'?'padding-top':'padding-bottom'}}" bindchange="swiperChange">
<swiper-item wx:for="{{tabs}}" wx:key="{{index}}" class="tab-contents">
<slot name="{{index}}"></slot>
</swiper-item>
</swiper>
</view>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 组件的方法列表
*/
methods: {
toggleTab: function (e) {
var index = e.currentTarget.dataset.index
if (this.data.activeIndex === index) {
return false;
} else {
this.setData({
activeIndex: index,
cur: index
})
}
var myEventOption = { activeIndex: index } // 触发事件的选项
this.triggerEvent('myevent', myEventOption)
},
swiperChange: function(e) {
var activeIndex = e.detail.current
this.setData({
activeIndex
})
var myEventOption = { activeIndex } // 触发事件的选项
this.triggerEvent('myevent', myEventOption)
}
}