微信小程序--组件 下拉加载下一页(scroll-view 并防止抖动)

发布于:2024-05-07 ⋅ 阅读:(30) ⋅ 点赞:(0)

.wxml

 <scroll-view class="body-container" scroll-top="{{scrollTop}}"  scroll-y="true" bindscrolltolower="bindDownLoad" bindscrolltoupper="topLoad" bindscroll="scroll">
  <view class="content-view">
      <view  wx:for="{{newsList}}" wx:key="newsId">
        {{item.name}}
      </view>
    </view>
    <view class="loading-view">
      <view hidden="{{!loading}}">
        加载中<div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
      </view>
      <view hidden="{{!loadingComplete}}">
        已加载全部
      </view>
    </view>
  </scroll-view>

.js

// homePage/index/index.js
const httpUtils = require("../../utils/httpUtils")
const app = getApp()
var total = 0
var pageNo = 1
const pageSize = 20
Component({
  /**
   * 组件的属性列表
   */
  properties: {},

  lifetimes: {
    created: function () {
    },
    attached: function () {
      setTimeout(() => {
        this.getListHome('fresh')
      }, 0)
    },
    ready: function () {}
  },

  /**
   * 组件的初始数据
   */
  data: {
    timer: null,
    scrollTop: 0,
    loading: false,
    loadingComplete: false,
    newsList: [],
  },

  /**
   * 组件的方法列表
   */
  methods: {
    //下拉加载
    bindDownLoad: function () {
      this.loadData()
    },
    scroll: function (event) {
      if (this.timer) {
        clearTimeout(this.timer)
      }
      //定时器在滚动加载时防止抖动
      this.timer = setTimeout(() => {
        this.setData({
          scrollTop: event.detail.scrollTop,
        });
      }, 2000);
      this.setData({
        isFixed: event.detail.scrollTop >= 150 ? true : false
      });
      if (event.detail.scrollTop >= 600) {
        this.setTouchShow(true)
      } else {
        this.setTouchShow(false)
      }
    },
    //上拉刷新
    topLoad: function () {
      //数据刷新
      this.resetData()
    },
    joinEnterprise() {
      wx.showToast({
        title: '功能暂未开放',
        icon: 'error'
      })
    },
    //页面出现时调用
    resetData() {
      pageNo = 1
      total = 0
      pageNo = 1
      this.getListHome('fresh')
    },
    loadData(action) {
      if (action == 'fresh') {
        pageNo = 1
      }
      if (action == 'more') {
        if (pageNo * pageSize < total) {
          pageNo++
          this.getListHome('more')
        }
      } else {
        this.getListHome('fresh')
      }
    },
    getListHome(type) {
      let url = ""
      this.setData({
        loading: true,
      })
      httpUtils.post({
        url: url,
        data: {
          page: pageNo,
          pageSize: pageSize,
        }
      }).then(res => {
        // wx.hideLoading()

        total = res.total;
        this.setData({
          loading: false,
          loadingComplete: pageNo * pageSize <= total ? false : true,
        })
        let newsList = res.records||[]
        if (type == 'fresh') {
          this.setData({
            newsList: newsList
          })
        } else {
          this.setData({
            newsList: this.data.newsList.concat(newsList)
          })
        }
        this.setData({
          noData: this.data.newsList.length ? false : true
        })
      }).finally(err => {
        this.setData({
          loading: false,
          loadingComplete: pageNo * pageSize <= total ? false : true,
        })
        this.setData({
          noData: this.data.newsList.length ? false : true
        })
      })
    },

    //回到顶部,内部调用系统API
    goTopOn() {
      this.setData({
        scrollTop: 0
      })
      if (wx.pageScrollTo) {
        wx.pageScrollTo({
          scrollTop: 0
        })
      } else {
        wx.showModal({
          title: '提示',
          content: '当前微信版本过低,暂无法使用该功能,请升级后重试。'
        })
      }
    },

    setTouchShow(touchShow) {
      this.setData({
        touchShow
      })
    },
  }
})

.wxss

.body-container {
  margin-top: 400rpx;
  display: flex;
  flex-direction: column;
  border-top-left-radius: 40rpx;
  border-top-right-radius: 40rpx;
  z-index: 9;
  position: sticky;
  width: 100vw;
  height: 66vh;
}
.loading-view {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  height: 100rpx;
  margin-top: 20rpx;
  font-size: 32rpx;
}

@keyframes blink {
  0% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #333;
  margin: 0 5px;
  animation: blink 1.4s infinite both;
}

.dot:nth-child(2) {
  animation-delay: 0.7s;
}

.dot:nth-child(3) {
  animation-delay: 1.4s;
}

底部loading动画

<view hidden="{{!loading}}">
  加载中<div class="dot"></div>
  <div class="dot"></div>
  <div class="dot"></div>
</view>    

@keyframes blink {
  0% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #333;
  margin: 0 5px;
  animation: blink 1.4s infinite both;
}

.dot:nth-child(2) {
  animation-delay: 0.7s;
}

.dot:nth-child(3) {
  animation-delay: 1.4s;
}