1. 业务需求
当下图中上部分的classifyList分类数据渲染完毕之后,获取一遍tab选项卡距离页面顶部的距离,有了这个距离进行其他操作;
因为classifyList分类这部分数据是后台可配置的,不确定是会渲染一行还是两行,因此卡片高度不能直接写一个固定高度;需要在classifyList数据渲染完毕之后获取一遍tab选项卡距离页面顶部的距离。
效果图:
在使用vue或者uniapp时,有时候需要在页面数据渲染完成之后调用方法,不然获取不到准确的数据,特别是在获取列表数据高度的时候,由于数据没有加载完,获取不到准确的高度。
然后就想到了vue中的两个知识点 this.$nextTick
和watch
2. 关于nextTick和watch
nextTick
:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
watch
:
用于观察Vue实例上的数据变化,对应一个对象,键是需要观察的表达式,值是对应的回调函数。值也可以是方法名,或者包含选项的对象。
3. 出现的问题
之前是这样子使用nextTick的:
mounted () {
this.$nextTick(() => {
//调用方法
this.getElementScollTop()
})
}
发现上面这种方法,实现不了上面所说的效果,只是Dom结构渲染完毕,但是没有数据
,所以获取tab距离页面顶部的高度不准确。
4. 正确的解决方法
正确的是,需要watch监听某个属性
。
export default {
data() {
flag: true, //默认true
},
watch: {
classifyList() {
//只有在页面获取完一遍classifyList数据完毕后,再更改 this.flag = false,防止不必要的bug
if (this.flag == true) {
this.$nextTick(() => {
this.getElementScollTop()
this.flag = false
})
}
},
},
methods:{
//获取tab离页面顶部的距离
getElementScollTop() {
const query = uni.createSelectorQuery()
query
.select('.tab-con')
.boundingClientRect((data) => {
console.log(data, 'data')
this.pageScrollTop = Math.round(data.top)
})
.exec()
},
}
}
5. 只监听一次某数据变化
获取tab距离页面的高度是为了计算滑动距离,只需要进页面获取一次即可。因此使用flag
变量标识,获取结束则修改为false
。这种写法经常会遇到,记录下。
需要设一个变量 flag:true; 监听到某个值变化 classifyList,改 flag:false;
6. 需要在加载中时,防止用户提前滑动页面
需要注意的是,当用户一进页面就滑动的时候,我们获取的高度也会发生变化。因此需要进入页面设置加载中,防止用户误触碰,加载结束之后,我们就能获取到正确的高度了。
onLoad(e) {
uni.showLoading({
title: '加载中',
mask: true, //显示透明蒙层,防止触摸穿透
})
//下面是自己的业务逻辑
}