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

.wxml

javascript 复制代码
 <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

javascript 复制代码
// 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

javascript 复制代码
.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动画

javascript 复制代码
<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;
}
相关推荐
黄华SJ520it12 小时前
线上线下多门店融合系统开发指南
小程序·系统开发
一孤程1 天前
Airtest自动化测试第五篇:小程序与Web测试——跨平台自动化全覆盖
前端·自动化测试·小程序·自动化·测试·airtest
CRMEB定制开发1 天前
开源商城源码下载后怎么搭建?五步走通完整流程
小程序·开源·商城系统·私域运营
JudithHuang2 天前
受够了带广告的单位换算 App,我自己做了一个微信小程序
微信小程序
小羊Yveesss2 天前
2026年如何自己搭建一个外贸网页?单页验证和完整网站的区别
微信小程序·小程序·开源
weishuangyun1232 天前
怎么开发自己的小程序?2026 三种主流方式实测对比
小程序
言乐62 天前
Python视频相对亮度检测
数据库·python·计算机视觉·小程序·音视频
2501_916008892 天前
iOS 证书管理最佳实践 从创建到续期的完整指南
android·ios·小程序·https·uni-app·iphone·webview
小羊Yveesss2 天前
2026年微信小程序搭建一般需要多长时间?不同方案周期和延期点
微信小程序·小程序
禾高网络2 天前
互联网医院|AI 互联网医院成品开发系统
java·大数据·人工智能·小程序