微信小程序列表加载更多

这篇具有很好参考价值的文章主要介绍了微信小程序列表加载更多。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

基于小程序开发的列表加载更多例子。

详细

一、前言

基于小程序开发的列表加载更多例子。

二、运行效果

运行效果(演示的小视频,点击播放即可)

三、实现过程

总体思路如何:

1、通过scroll-view组件提供的bindscroll方法监控滚动的时候是否距离底部在40px内,如果小于40px则触发加载更多方法(见完整代码index.js里的bindscroll方法)

2、通过使用发现很多时候服务返回数据太快了,没有加载等待的过程,显的不自然,所以在loadMore方法里通过setTimeout来保证至少有333毫秒的加载时间(见完整代码index.js里的loadMore方法)

3、实际使用中又发现一个问题,上滑到底部会重复触发加载更多方法导致重复的网络请求。通过记录上次加载时间lastRequestTime,保证两次网络请求的间隔大于1秒(见完整代码index.js里的fetchList方法),这样就能避免重复调用加载更多的问题

备注:demo代码里的网络请求wx.requestTest方法是为了显示效果,所以写了个模拟的请求方法,实际使用可替换为wx.request对接自己项目的服务

具体实现如下:

1、创建小程序,点击下图里框起来的位置,创建小程序

微信小程序列表加载更多,前端,微信小程序,小程序

微信小程序列表加载更多,前端,微信小程序,小程序

2、在app.js里添加网络模拟方法

let serverData = [];
for(let i = 1; i < 25; i++){
  serverData.push({id:i, name:i})
}
App({
  onLaunch: function () {
    wx.requestTest = ({data:{page,size},success}) => {
      setTimeout(
        () => {
          //模拟网络返回请求
          let res = {
            data:{
              data:{
                rows: serverData.slice((page - 1) * size, size + (page - 1) * size)
              },
              result: true,
            }
          }
          console.log(res)
          success(res)
        },1000//模拟网络延迟
      )
    }
  },
  globalData: {
  }
})

3、增加和pages同层级的components文件夹,在里面创建Loading文件夹,并在下面创建以下文件

//loading.js
Component({
  data: {
  },
  properties: {
    visible: {//loading效果是否显示
      type: Boolean,
      value: false//默认不显示
    },
  },
})
//loading.json
{
  "component": true,//表示是组件
  "usingComponents": {}
}
//loading.wxss
.loadmore {
  width: 100%;
  height: 0rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top:24rpx;
  transition: all 200ms linear;
}
.loadmore.visible {
  height: 80rpx;
}
.my-loading:after {
  content: " ";
  display: block;
  width: 26px;
  height: 26px;
  margin: 1px;
  border-radius: 50%;
  border: 2px solid #FFD800;
  border-color: #fff transparent #FFD800 transparent;
  animation: lds-dual-ring 1.2s linear infinite;
}
@keyframes lds-dual-ring {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
//loading.wxml
<view class="loadmore {{visible && 'visible'}}">
  <view class="my-loading" wx:if="{{visible}}"></view>
</view>

4、修改pages/index文件夹下各文件如下

//index.json
{
  "navigationBarTitleText": "首页",
  "usingComponents": {
    "loading": "/components/Loading/loading"//引用组件
  }
}
//index.js
const app = getApp()
let loadingMore = false
let lastScollTop = 0;
let lastRequestTime = 0;
Page({
  data: {
    list: [],
    hasMore: true,//列表是否有数据未加载
    page: 1,
    size: 8,//每页8条数据
    scrollYHeight: 0,//scroll-view高度
  },
  bindscroll: function (e) {
    const { scrollHeight, scrollTop } = e.detail;
    const { scrollYHeight, hasMore } = this.data;
    //如果当前没有加载中且列表还有数据未加载,且页面滚动到距离底部40px内
    if (!loadingMore && hasMore && (scrollHeight - scrollYHeight - scrollTop < 40) && lastScollTop <= scrollTop) {
      this.loadMore()
    }
    lastScollTop = scrollTop
  },
  loadMore: function () {
    const { page, hasMore } = this.data;
    if (!hasMore || loadingMore) return;
    loadingMore = true
    setTimeout(
      () => {
        this.fetchList(page + 1, () => {
          loadingMore = false;
        })
      }, 333
    )
  },
  fetchList: function (page, cb) {
    let nowRequestTime = (new Date()).getTime();
    //限制两次网络请求间隔至少1秒
    if (nowRequestTime - lastRequestTime < 1000) {
      if (cb) cb();
      return;
    }
    lastRequestTime = nowRequestTime
    //这里wx.requestTest实际使用时换成wx.request
    //wx.requestTest定义见app.js
    wx.requestTest({
      url: "testUrl",
      header: {
        'Authorization': wx.getStorageSync('token')
      },
      data: {
        page,
        size: this.data.size,
      },
      success: (res) => {
        if (res.data && res.data.result) {
          let list = res.data.data.rows || [];
          if (list.length == 0) {
            this.setData({
              hasMore: false,
              page,
            })
          } else {
            this.setData({
              list: this.data.list.concat(list),
              hasMore: list.length == this.data.size,
              page,
            })
          }
        } else {
          wx.showToast({
            title: res.data ? res.data.message : "列表加载失败",
            icon: 'none',
            duration: 1000
          })
        }
        if (cb) {
          cb()
        }
      },
      fail: () => {
        wx.showToast({
          title: "列表加载失败",
          icon: 'none',
          duration: 1000
        })
        if (cb) {
          cb()
        }
      }
    })
  },
  onReady: function () {
    wx.getSystemInfo({
      success: ({ windowHeight }) => {
        this.setData({ scrollYHeight: windowHeight })//设置scrill-view组件的高度为屏幕高度
      }
    })
  },
  onLoad: function () {
    this.fetchList(1)//加载第一页数据
  }
})
//index.wxml
<scroll-view scroll-y style="height:{{scrollYHeight}}px"   scroll-top="{{scrollTop}}" bindscroll="bindscroll">
    <view
      class="item"
      wx:for="{{list}}"
      wx:key="id"
      wx:for-index="idx"
    >
      {{item.name}}
    </view>
    <loading visible="{{hasMore}}"></loading>
</scroll-view>
//index.css
.item {
  width: 750rpx;
  height: 200rpx;
  font-size: 40rpx;
  color: black;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.item::after{
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-bottom: 1rpx solid #eeeeee;
}

此时运行程序,可查看效果。
 

整体代码:

//index.js
const app = getApp()
let loadingMore = false
let lastScollTop = 0;
let lastRequestTime = 0;
Page({
  data: {
    list: [],
    hasMore: true,//是否有数据未加载
    page: 1,
    size: 8,
    scrollYHeight: 0,
  },
  bindscroll: function (e) {
    const { scrollHeight, scrollTop } = e.detail;
    const { scrollYHeight, hasMore } = this.data;
    //如果当前没有加载中且列表还有数据未加载,且页面滚动到距离底部40px内
    if (!loadingMore && hasMore && (scrollHeight - scrollYHeight - scrollTop < 40) && lastScollTop <= scrollTop) {
      this.loadMore()
    }
    lastScollTop = scrollTop
  },
  loadMore: function () {
    const { page, hasMore } = this.data;
    if (!hasMore || loadingMore) return;
    loadingMore = true
    setTimeout(
      () => {
        this.fetchList(page + 1, () => {
          loadingMore = false;
        })
      }, 333
    )
  },
  fetchList: function (page, cb) {
    let nowRequestTime = (new Date()).getTime();
    if (nowRequestTime - lastRequestTime < 1000) {
      if (cb) cb();
      return;
    }
    lastRequestTime = nowRequestTime
    //这里wx.requestTest实际使用时换成wx.request
    //wx.requestTest定义见app.js
    wx.requestTest({
      url: "testUrl",
      header: {
        'Authorization': wx.getStorageSync('token')
      },
      data: {
        page,
        size: this.data.size,
      },
      success: (res) => {
        if (res.data && res.data.result) {
          let list = res.data.data.rows || [];
          if (list.length == 0) {
            if(page == 1){
              this.setData({
                hasMore: false,
                page,
                list: []
              })
            }else {
              this.setData({
                hasMore: false,
                page,
              })
            }
          } else {
            this.setData({
              list: this.data.list.concat(list),
              hasMore: list.length == this.data.size,
              page,
            })
          }
        } else {
          wx.showToast({
            title: res.data ? res.data.message : "列表加载失败",
            icon: 'none',
            duration: 1000
          })
        }
        if (cb) {
          cb()
        }
      },
      fail: () => {
        wx.showToast({
          title: "列表加载失败",
          icon: 'none',
          duration: 1000
        })
        if (cb) {
          cb()
        }
      }
    })
  },
  onReady: function () {
    const { windowWidth, ratio } = app.globalData
    wx.getSystemInfo({
      success: ({ windowHeight, pixelRatio }) => {
        this.setData({ scrollYHeight: windowHeight })
      }
    })
  },
  onLoad: function () {
    this.fetchList(1)
  }
})
 
//index.wxml
<scroll-view scroll-y style="height:{{scrollYHeight}}px"   scroll-top="{{scrollTop}}" bindscroll="bindscroll">
    <view
      class="item"
      wx:for="{{list}}"
      wx:key="id"
      wx:for-index="idx"
    >
      {{item.name}}
    </view>
    <loading visible="{{hasMore}}"></loading>
</scroll-view>
 
//index.css
.item {
  width: 750rpx;
  height: 200rpx;
  font-size: 40rpx;
  color: black;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.item::after{
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-bottom: 1rpx solid #eeeeee;
}
 
//app.js
let serverData = [];
for(let i = 1; i < 25; i++){
  serverData.push({id:i, name:i})
}
App({
  onLaunch: function () {
    wx.requestTest = ({data:{page,size},success}) => {
      setTimeout(
        () => {
          //模拟网络返回请求
          let res = {
            data:{
              data:{
                rows: serverData.slice((page - 1) * size, size + (page - 1) * size)
              },
              result: true,
            }
          }
          console.log(res)
          success(res)
        },1000//模拟网络延迟
      )
    }
  },
  globalData: {
  }
})
三、项目结构

微信小程序列表加载更多,前端,微信小程序,小程序



  •  
四、其他补充

暂时没有

 文章来源地址https://www.toymoban.com/news/detail-667195.html

到了这里,关于微信小程序列表加载更多的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【python进阶】列表排序已经掌握?这种将变量插入列表序列的方法你该知道了

    🙋‍♂️作者简介:生鱼同学,大数据科学与技术专业硕士在读👨‍🎓,曾获得华为杯数学建模国家二等奖🏆,MathorCup 数学建模竞赛国家二等奖🏅,亚太数学建模国家二等奖🏅。 ✍️研究方向:复杂网络科学 🏆兴趣方向:利用python进行数据分析与机器学习,数学建模竞

    2023年04月08日
    浏览(43)
  • python经典有序序列的list列表推导式

    生成一个数据列表 使用列表推导式生成该数据列表 分析: 1、使用一行代码的列表推导式就完成了该列表的生成 2、[i for i in range(20)],第一个i元素代表向列表list_2中添加的元素 3、[i for i in range(20)],第二个i元素代表for循环遍历的i元素 使用列表推导式生成只有偶数的数据列

    2024年02月02日
    浏览(60)
  • 【Python 笔记(二)——基本语句 变量类型 字符串 序列 列表与元组 字典与集合】

    在 Python 中,基本语句可以帮助我们完成一些基本的操作,如控制流程、定义函数等。以下是 Python 中的几种基本语句: if 语句 if 语句用于判断某个条件是否成立,如果条件成立则执行相应的代码块。 for 语句 for 语句用于遍历序列中的元素,依次执行相应的代码块。 while 语

    2024年02月08日
    浏览(50)
  • 微信小程序之加载更多(分页加载)实例 —— 微信小程序实战系列(2)

    let that = this; let searchKeyword = that.data.searchKeyword,//输入框字符串作为参数 searchPageNum = that.data.searchPageNum,//把第几次加载次数作为参数 callbackcount =that.data.callbackcount; //返回数据的个数 //访问网络 util.getSearchMusic(searchKeyword, searchPageNum,callbackcount, function(data){ console.log(data) //判断是否

    2024年04月11日
    浏览(40)
  • 微信小程序学习实录2(下拉刷新、下拉加载更多、小程序事件、PHP后端代码、刷新无数据解决方案)

    lazyCodeLoading基础库 2.11.1 及以上版本支持,2.11.1 以下兼容但无优化效果 通常情况下,在小程序启动期间,所有页面及自定义组件的代码都会进行注入,当前页面没有使用到的自定义组件和页面在注入后其实并没有被使用。自基础库版本 2.11.1 起,小程序支持有选择地注入必要

    2024年02月05日
    浏览(52)
  • 微信小程序商城搭建--后端+前端+小程序端

    前端技术:React、AntdesignPro、umi、JavaScript、ES6、TypeScript、 小程序 后端技术:Springboot、Mybatis、Spring、Mysql 后端采用Springboot搭配前端React进行开发,完成用户管理、轮播图管理、一级分类管理、商品管理、日志管理。 支持多图上传功能,封面图。 采用JWT+拦截器进行接口拦截

    2024年02月05日
    浏览(52)
  • uniapp-微信小程序实现swiper左右滚动切换tab,上下滚动加载列表

    思路:左右滑动使用swiper,上下滑动用scroll-view,swiper改变时同时改变tab并更新列表 坑点: 1. swiper高度问题,导致滑动不到最底部和最顶部         需要手动计算,减去顶部高度和底部tabbar,并且需要同时设置padding-top和paddin-botton,否则列表显示不完整 2. 由于最开始的代码

    2024年02月04日
    浏览(64)
  • 微信小程序开发---条件渲染和列表渲染

    目录 一、条件渲染 (1)基本使用  (2)block (3)hidden 二、列表渲染 (1)基本使用 (2)手动指定索引和当前项的变量名 (3)wx:key的使用 条件渲染就相当于if语句,这也不需要多说了,终点是它的用法。 如果想要一次性控制多个组件的展示和隐藏,可以使用block标签将多

    2024年02月09日
    浏览(52)
  • 微信小程序实现上拉加载更多

    一、前情提要 微信小程序中实现上拉加载更多,其实就是pc端项目的分页。 使用的是scroll-view,scroll-view详情在微信开发文档/开发/组件/视图容器中。 每次上拉,就是在原有数据基础上,拼接/合并上本次上拉请求得到的数据。 这里采用的是concat,concat 是数组对象的一个方法

    2024年04月27日
    浏览(36)
  • 微信小程序-上拉加载更多和下拉刷新

    页面配置文件中配置 \\\"enablePullDownRefresh\\\": true 开启下拉刷新 设置 onPullDownRefresh 方法 在用户下拉时会调用 onPullDownRefresh 方法 在完成后需要调用 wx.stopPullDownRefresh() 关闭刷新状态 可以在页面配置文件中配置 \\\"onReachBottomDistance\\\":50 来设置触发上拉加载的距离,单位为 px 。 默认:

    2024年02月15日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包