1. 业务需求

当下图中上部分的classifyList分类数据渲染完毕之后,获取一遍tab选项卡距离页面顶部的距离,有了这个距离进行其他操作;
因为classifyList分类这部分数据是后台可配置的,不确定是会渲染一行还是两行,因此卡片高度不能直接写一个固定高度;需要在classifyList数据渲染完毕之后获取一遍tab选项卡距离页面顶部的距离。

效果图:

在这里插入图片描述

在使用vue或者uniapp时,有时候需要在页面数据渲染完成之后调用方法,不然获取不到准确的数据,特别是在获取列表数据高度的时候,由于数据没有加载完,获取不到准确的高度。

然后就想到了vue中的两个知识点 this.$nextTickwatch

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,  //显示透明蒙层,防止触摸穿透
    })
    //下面是自己的业务逻辑
 }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐