Movable-view实现列表的下拉刷新上拉加载

微信小程序自身有下拉刷新的动态效果,但是这个效果只针对page,如果需要只对其中的某个滚动的子元素做下拉的效果,是没法实现的,当然还有scroll-view,但是scroll-view在到达顶部和底部的时候比较生硬,没有回弹的效果,所以我就想有没有方法能实现这个回弹的效果。

我试了以下三种方法

1.使用better-scroll和mpvue

使用better-scroll插件,用vue的方式写滚动列表,实现了简单的下拉刷新上拉加载,better-scroll本身就有滚动回弹的效果,写完之后,在浏览器里看是没问题了,但是经过mpvue编译成小程序之后,初始化better-scroll对象的时候直接报错了,我估计是因为better-scroll有使用到dom对象,但是小程序里面是没有dom对象的,具体的原因我没有深究。

2.使用小程序的movable-view和scroll-view实现列表

使用movable-view,里面嵌套scroll-view,movable-view和scroll-view的宽高是一样的,这样使用的话是可以滚动的,但是在开发者工具里面没有回弹的效果,和直接使用scroll-view差不多,手机上倒是有滚动回弹的效果,这样开发的时候就没办法用了。

3.动态计算movable-view的高度

使用movable-view,movable-view里面只有一个直接子节点,一个普通的view,姑且称这个view为content,content不给高度,靠里面的元素来撑高,然后在onReady里面获取到content的高度,赋值给movable-view,是的movable-view的高度和content的高度一致,这样就可以了。上拉加载和下拉刷新主要是监听change事件,判断他的位置,当content的内容改变的时候,再重新获取一下content的高度赋值给movable-view即可。但是这个还有点问题,就是不能在app.json中使用usingComponents,也不能在页面的json文件里面使用这个属性,也就是不能使用自定义组件。具体问题还不知道为什么,可能是微信小程序的一个bug吧,使用了之后page的宽高和movable-view的位置会变得很奇怪。

下面是我的代码

<view class='container'>
  <movable-area class='area'>
    <movable-view class='view' style="height: {{h}}px;" direction="vertical" inertia out-of-bounds>
      <view class='content'>
        <view class='box' wx:for="{{list}}" wx:key="{{index}}">{{index}}</view>
      </view>
    </movable-view>
  </movable-area>
</view>


page {
  width: 100%;
  height: 100%;
}

.container {
  width: 100%;
  height: 100%;
}

.box {
  width: 100%;
  height: 200rpx;
  background-color: #FFEE00;
}

.area {
  width: 100%;
  height: 100%;
}

.view {
  width: 100%;
}




Page({
  data: {
    isReseting: false //正在回弹
  },
  onLoad: function() {

    let list = [];
    for (let i = 0; i < 10; i++) {
      list.push(i);
    }
    this.setData({
      list
    })
  },
  onReady: function() {
    const query = wx.createSelectorQuery();
    query.select('.area').boundingClientRect(res => {
      this.data.areaH = res.height;
    }).exec();
    this.refresh();
  },
  refresh: function() {
    const query = wx.createSelectorQuery();
    query.select('.content').boundingClientRect(res => {
      this.setData({
        h: res.height
      });
    }).exec();
  },
  change: function (e) {
    if (e.detail.source === 'out-of-bounds') {

      if (e.detail.y < (this.data.areaH - this.data.h - 10)) {
        //到达下拉刷新的条件
        if (!this.data.isReseting) {
          //控制在回弹钱不再触发
          this.data.isReseting = true;
          let list = [];
          for (let i = 10; i < 20; i++) {
            list.push(i);
          }
          this.setData({
            list: this.data.list.concat(list)
          })

          this.refresh();
        }
      } else if (e.detail.y === 0) {
        this.data.isReseting = false;
      }
    }
  }
})


    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章