在uniapp开发小程序时,如果想要实现类似于微信的字母滑动的索引效果,在这样一个需求中,首先想到的肯定是能不能通过ref的操作来实现,毕竟uniapp就是基于vue进行编写代码的风格,但是在微信小程序中,是没有dom的,也就是说是不能通过ref来获取到dom数据的,那应该如何进行处理呢?别急,uniapp为此提供了对应的方法uni.createSelectorQuery(),这个方法返回一个 SelectorQuery 对象实例。可以在这个实例对象上使用 select 等方法选择节点,并使用 boundingClientRect 等方法选择需要查询的信息。废话不多说上代码:
<!--定义标签(这里省略了一些vue代码,请多注意)-->
<view class="letters"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend">
<view class="item"
:class="item1 == letter_item?'item-click':''"
v-for="item1 in letters"
@click="letter_click(item1)"
:id="item1">{{item1}}</view>
</view>
<script>
export default {
data:{
return {
//定义好字母数据,在标签上通过v-for遍历填写进入标签内容
letters:['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','#'],
letter_item:"
}
},
methods:{
//标签上需要监听触摸事件(触摸开始、触摸移动、触摸结束)
//触摸开始事件中获取到对应的节点信息,主要是id、top、bottom,下面在移动时会进行top和bottom匹配
touchstart(e){
const query = uni.createSelectorQuery().in(this);
query.selectAll('.letters .item')
.boundingClientRect(data => {
this.arrTouchBarPosition = data
})
.exec();
},
/*触摸移动过程中,通过触摸事件的e参数,获取到当前移动的节点位置信息clientY,再对触摸开始事件中获取的字母节点信息进行遍历,判断clientY是否和遍历出的节点的top和bottom,如果大于top并且小于bottom,说明触摸滑动正好在当前的这个字母节点的区间范围内,将提前定义好的letter_item赋值*/
touchmove(e){
let clientY = e.touches[0].clientY;
for (let item of this.arrTouchBarPosition) {
if (clientY >= item.top && clientY <= item.bottom) {
this.letter_item = item.id
//根据自己定义的筛选方法在这里执行一下就可以了
//顺便说一下,在循环中不能使用break进行结束,需要使用continue
continue;
}
}
},
touchend(e){
//虽然说在滑动过程中会进行筛选处理,但是在触摸结束时最好也对数据进行一次筛选
},
//点击事件
letter_click(item1){
this.letter_item = item1//主要用于做样式绑定的
}
}
}
</script>
<style>
//样式我就省略了,重点在逻辑
</style>