2021-07-11
用的better-scroll实现的地址上拉刷新和下拉加载,better-scroll主要的注意事项,最主要的是父元素要固定宽度,可用flex:1来固定,子元素宽度自动撑开就好。
主要的实现效果和思路
点击跳转到具体位置,比如点到右边字母区域A,就会自动跳转到A区域
运用better-scroll的一个api,scrollToElement
props: {
cityData: Object,
hotCities: Array,
targetEl: String // 传过来的点击时候的元素
},
watch: {
targetEl () {
if(this.targetEl){
// 滚动到对应元素
this.scroll.scrollToElement(this.$refs[this.targetEl][0])
}
}
},
mounted () {
let wrapper = this.$refs.listWrapper
this.scroll = new BScroll(wrapper)
this.$nextTick(() => {
this.scroll.refresh()
})
}
这里有个要注意的地方,需要DOM更新完毕之后,再刷新一下滚动元素 this.scroll,否则的话,写在mounted里面,滚动的元素是通过后端数据返回的,这时候后端数据还没得到,可能会有滚动不了的情况发生,所以需要再次刷新一下。
在字母区滑动,地址区域也会滑动
主要用到三个移动端手指触发事件,想要计算出是移动到了哪个字母。
- touchstart:手指触摸屏幕时候。去获取A字母距离顶端的距离
- touchmove:手指在屏幕移动的时候。可以得到手指距离顶部的距离,每一个移动的动作,都会有对应的手指的位置,手指的位置 - A字母距离顶端的距离,从而计算出此刻移动的这个字母到A字母的距离/22(每个字母的高度),就可以计算出移动到哪个字母的下标了。
- touchend:手指离开屏幕的时候
主要的实现代码
<template>
<div class="al-list">
<ul class="al-box">
<li
class="item"
v-for="item of alArray"
:key="item"
:ref="item"
@click="getAlphbat"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
{{ item }}
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
aHeight: '',
touchFlag: false // 要不要触发移动move事件标识值
}
},
props: {
cityData: Object
},
computed: {
alArray () {
const alArray = Object.keys(this.cityData)
return alArray
}
},
methods: {
getAlphbat (e) {
this.$emit('change', e.target.innerText)
// this.targetEl = e.target.innerText
},
handleTouchStart () {
this.touchFlag = true
// this.height没有值才会去获取,否则还是用原来的this.height
// 获取A元素到父元素顶部的距离
if(!this.aHeight){
this.aHeight = this.$refs['A'][0].offsetTop
}
},
handleTouchMove (e) {
if(this.touchFlag){
// 移动到某个元素的下标
let moveLetterIndex = Math.floor((e.touches[0].clientY - this.aHeight) / 22)
this.$emit('change', this.alArray[moveLetterIndex])
}
},
handleTouchEnd () {
// 手指一离开字母表区域,就不能触发移动move事件
this.touchFlag = false
}
}
}
</script>
<style lang='stylus' scoped>
@import '~@assets/mixin.styl';
.al-list {
height: 100%;
width: 20px;
position: absolute;
top: 0;
right: 0;
.al-box {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.item {
text-align: center;
padding: 5px 0;
color: $themColor;
}
}
}
</style>
总结
几个易混的知识点总结如下:
for in和for of的区别computed计算属性需要有返回值- 遍历对象,可以用
Object.keys(obj):遍历键名;Object.values(obj):遍历键值