先来看看效果
项目结构大概是这样
点击切换主要是兄弟组件之间的传值,本篇不再介绍,这里主要是滑动改变CityList中的列表的位置
<template>
<ul class="list">
<li class="item"
v-for="item of letters"
:key="item"
@click="handleLetterClick"
>
{{ item }}
</li>
</ul>
</template>
这里的item是循环出来的是A,B,C···
触摸滑动定位当然要知道有没有触摸
在data中定义一个touchStatus
data() {
return {
touchStatus: false
}
},
在li标签上监听三个事件
<li class="item"
v-for="item of letters"
:key="item"
:ref="item"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
@click="handleLetterClick"
>
{{ item }}
</li>
methods: {
//这是点击时向父组件传值
handleLetterClick: function(e) {
this.$emit('change', e.target.innerText)
},
//这是触摸开始时将touchStatus改为true
handleTouchStart: function() {
this.touchStatus = true
},
//触摸移动时触发
handleTouchMove: function(e) {
//判断是否开始触摸
if (this.touchStatus) {
//获取第一个字母A距离此组件顶部(搜索框下边缘)的距离
const startY = this.$refs['A'][0].offsetTop
//获取当前触摸位置距离搜索框下边缘的位置
//79是我的CityHeader和搜索框的高度
const touchY = e.touches[0].clientY - 79
//touchY - startY是触摸位置到A的上边缘的位置
//20是每个字母的高度
//计算后向下取整便可得到当前触摸到第几个字母
const index = Math.floor((touchY - startY) / 20)
//判断index是否合理,防止触摸到外部时引发不必要的BUG
if (index >= 0 && index < this.letters.length) {
//将index传到父组件
this.$emit('change',this.letters[index])
}
}
},
//触摸结束后将touchStatus改回false
handleTouchEnd: function() {
this.touchStatus = false
}
}
这样就可以获取到了当前触摸的位置,要更改的话需要把值传递到CityList组件中更改,想要切换可以去看看我的另一篇文章—Vue中兄弟组件间的传值
基本思路就是通过触摸时的位置再配合上相应字母的位置来计算出此时触摸到的位置