当前位置: 首页 > news >正文

微信小程序列表加载更多

概述

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

详细

一、前言

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

二、运行效果

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

三、实现过程

总体思路如何:

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、创建小程序,点击下图里框起来的位置,创建小程序

image.png

image.png

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 = truesetTimeout(() => {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.jswx.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"><viewclass="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 = truesetTimeout(() => {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.jswx.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.globalDatawx.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"><viewclass="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: {}
})

三、项目结构

WX20180719-134632@2x.png



  •  

四、其他补充

暂时没有

 

相关文章:

微信小程序列表加载更多

概述 基于小程序开发的列表加载更多例子。 详细 一、前言 基于小程序开发的列表加载更多例子。 二、运行效果 运行效果&#xff08;演示的小视频&#xff0c;点击播放即可&#xff09; 三、实现过程 总体思路如何&#xff1a; 1、通过scroll-view组件提供的bindscroll方法…...

数据库知识

怎么做 常见的数据库 Oracle Mysql SOLSever Navicat &#xff08;新版可以链接mysql oracle&#xff09; http://sqlfiddle.com/ 数据库操作在线练习 mysql自带四个数据库 数据库语言的使用 显示数据库&#xff1a;show databases&#xff1b; 创建数据库&#xff1a;…...

VUE 目录介绍

更新升级&#xff08;npm - i&#xff09;之后最终目录如下&#xff1a; total 1672 drwxr-xr-x 18 testrose staff 576 8 22 02:53 . drwxr-xr-x 24 testrose staff 768 8 22 02:50 .. -rw-r--r-- 1 testrose staff 402 8 22 02:52 .babelrc -rw…...

Selenium的基本使用

文章目录 引入一.选择元素的基本方法1.根据id 选择元素2.根据 class属性选择元素当元素有 多个class类型 时 3.根据 tag名 选择元素4.通过WebElement对象选择元素5.find_element 和 find_elements 的区别 二.等待界面元素出现1.隐式等待2.显示等待 三.操控元素的基本方法1.点击…...

数据结构-----树的易错点

1.树的度和m叉树 •度为m的树&#xff08;度表示该结点有多少个孩子&#xff08;分支&#xff09;&#xff09; 任意结点的度<m(最多m个孩子) 至少又一个结点度m(有m个孩子) 一定是非空树&#xff0c;至少有m1个结点 •m叉树 任意结点的度<m(最多有m个孩子) 允许所…...

写之前的项目关于使用git remote -v 找不到项目地址的解决方案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、报错解析1. 报错内容2. 报错翻译3. 报错解析&#xff08;1&#xff09;使用git branch来查看git仓库有几个分支&#xff08;2&#xff09;使用git remote -v&am…...

STM32 F103C8T6学习笔记9:0.96寸单色OLED显示屏—自由取模显示—显示汉字与图片

今日学习0.96寸单色OLED显示屏的自由取模显示: 宋体汉字比较复杂&#xff0c;常用字符可以直接复制存下来&#xff0c;毕竟只有那么几十个字母字符&#xff0c;但汉字实在太多了&#xff0c;基本不会全部放在单片机里存着&#xff0c;一般用到多少个字就取几个字的模&#xff…...

直播平台源码搭建协议讲解篇:传输控制协议TCP

简介&#xff1a; 由于直播平台在当今时代发展的越来越迅速&#xff0c;使得直播平台的技术功能越来越智能&#xff0c;让用户在直播平台中能够和其他用户进行实时互动&#xff0c;让用户可以获取到全世界最新的资讯&#xff0c;让一些用户可以作为主播获得工作&#xff0c;让…...

中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题

最近研究搜索引擎、知识图谱和Python爬虫比较多&#xff0c;中文乱码问题再次浮现于眼前。虽然市面上讲述中文编码问题的文章数不胜数&#xff0c;同时以前我也讲述过PHP处理数据库服务器中文乱码问题&#xff0c;但是此处还是准备简单做下笔记。方便以后查阅和大家学习。 …...

基于Jenkins自动打包并部署Tomcat环境

目录 1、配置git主机 2、配置jenkins主机 3、配置web主机 4、新建Maven项目 5、验证 Jenkins 自动打包部署结果 Jenkins 的工作原理是先将源代码从 SVN/Git 版本控制系统中拷贝一份到本地&#xff0c;然后根据设置的脚本调用Maven进行 build&#xff08;构建&#xff09;。…...

开利网络受邀参与御盛马术庄园发展专委会主题会议

近日&#xff0c;开利网络受邀参与深度合作客户御盛马术庄园组织的首届发展专委会主体会议&#xff0c;就马术庄园发展方向进行沟通&#xff0c;数字化也是重要议题之一。目前&#xff0c;御盛马术庄园已经完成数字化系统的初步搭建&#xff0c;将通过线上线下相结合的方式搭建…...

【HarmonyOS北向开发】-05 ArkTS开发语言-ArkTS开发实践

...

无类别域间路由(Classless Inter-Domain Routing, CIDR):理解IP网络和子网划分(传统的IP地址类ABCDE:分类网络)

文章目录 无类别域间路由&#xff08;CIDR&#xff09;&#xff1a;理解IP网络和子网划分引言传统的IP地址类关于“IP地址的浪费” IP地址与CIDRIP地址概述网络号与主机号CIDR记法&#xff08;网络 网络地址/子网掩码&#xff09;网络和广播地址 CIDR的优势减少路由表项缓解IP…...

合宙Air724UG LuatOS-Air LVGL API-概念

概念 在 LVGL 中&#xff0c;用户界面的基本构建块是对象。例如&#xff0c;按钮&#xff0c;标签&#xff0c;图像&#xff0c;列表&#xff0c;图表或文本区域。 属性 基本属性 所有对象类型都共享一些基本属性&#xff1a; Position (位置) Size (尺寸) Parent (父母) Cli…...

【C语言】位段,枚举和联合体详解

目录 1.位段 1.1 什么是位段 1.2 位段的内存分配 1.3 位段的跨平台问题 2.枚举 2.1 枚举类型的定义 2.2 枚举的优点 3. 联合&#xff08;共用体&#xff09; 3.1 联合类型的定义 3.2 联合的特点 3.3 联合大小的计算 1.位段 1.1 什么是位段 位段的声明和结构体是类…...

python学习-文件管理

文件管理 shutil 文件拷贝 shutil.copy(src,dst) 注&#xff1a;srcrE:\python\.vscode\文件操作 windows上运行时候&#xff0c;如果不加r&#xff0c;上述文件路径在代码运行时会报错&#xff0c;因为其会先将双引号”“去掉&#xff0c;然后系统看到了文件路径中有\nc&…...

【LeetCode 算法】Number of Ways of Cutting a Pizza 切披萨的方案数-记忆化

文章目录 Number of Ways of Cutting a Pizza 切披萨的方案数问题描述&#xff1a;分析代码递归 Tag Number of Ways of Cutting a Pizza 切披萨的方案数 问题描述&#xff1a; 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; A…...

机器视觉之光流

光流&#xff08;Optical Flow&#xff09;是计算机视觉领域的一个重要概念&#xff0c;用于描述图像中物体的运动模式。光流可以用来跟踪图像中物体的运动&#xff0c;检测运动中的物体&#xff0c;或者在机器视觉任务中估计物体的速度和位移。 光流的基本思想是根据图像像素…...

C++:list使用以及模拟实现

list使用以及模拟实现 list介绍list常用接口1.构造2.迭代器3.容量4.访问数据5.增删查改6.迭代器失效 list模拟实现1.迭代器的实现2.完整代码 list介绍 list是一个类模板&#xff0c;加<类型>实例化才是具体的类。list是可以在任意位置进行插入和删除的序列式容器。list的…...

深度学习基础知识-pytorch数据基本操作

1.深度学习基础知识 1.1 数据操作 1.1.1 数据结构 机器学习和神经网络的主要数据结构&#xff0c;例如 0维&#xff1a;叫标量&#xff0c;代表一个类别&#xff0c;如1.0 1维&#xff1a;代表一个特征向量。如 [1.0&#xff0c;2,7&#xff0c;3.4] 2维&#xff1a;就是矩…...

Springboot使用QueryDsl实现融合数据查询

SpringbootQueryDsl技术 1、添加依赖 <!--基于JPA--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--QueryDSL支持--> <dependenc…...

解决方案 | 电子签打通消费电子行业数智化经营通路

技术迭代不断驱动产业快速增长&#xff0c;从PC电脑到手机平板、再到可穿戴设备的兴起&#xff0c;每一次设备的迭代都代表着技术为产品注入了新的发展动能。与此同时&#xff0c;消费电子设备迭代更新周期的不断缩短&#xff0c;市场增长疲缓等因素&#xff0c;也对行业的流转…...

JVM理论知识

一、JVM内存结构 java的内存模型主要分为5个部分&#xff0c;分别是&#xff1a;JVM堆、JVM栈、本地栈、方法区还有程序计数器&#xff0c;他们的用途分别是&#xff1a; JVM堆&#xff1a;新建的对象都会放在这里&#xff0c;他是JVM中所占内存最大的区域。他又分为新生区还…...

idea - 报错 Mybatis提示Tag name expected的问题< 小于号 无法识别

问题&#xff1a;Mybatis提示Tag name expected 原因&#xff1a; 当我们在mapper中编写sql语句的时候会发现使用"<“符号会提示一个Tag name expected。这是因为xml文件中不识别”<"符号和“&”符号。防止与xml本身的元素命名混淆&#xff0c;导致无法解…...

合宙Air724UG LuatOS-Air LVGL API--对象

对象 概念 在 LVGL 中&#xff0c;用户界面的基本构建块是对象。例如&#xff0c;按钮&#xff0c;标签&#xff0c;图像&#xff0c;列表&#xff0c;图表或文本区域。 属性 基本属性 所有对象类型都共享一些基本属性&#xff1a; Position (位置) Size (尺寸) Parent (父母…...

Java将PDF文件转为Word文档

Java将PDF文件转为Word文档 一、创建Springboot Maven项目 二、导入依赖信息 <repositories><repository><id>com.e-iceblue</id><url>https://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories&g…...

vite创建项目命令

1.第一步运行创建命令&#xff08;npm&#xff09; npm create vitelatest也可以使用yarn yarn create vite还可以 pnpm create vite注意的地方&#xff1a;首次创建的时候会出现这个 Need to install the following packages:create-vitelatest Ok to proceed? (y) 直接y就…...

解决Pandas KeyError: “None of [Index([...])] are in the [columns]“问题

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)

【2023】前端加springboot实现Web Socket连接通讯&#xff08;包括后端实现心跳检测&#xff09; 一级目录二级目录三级目录 前言一、Web Socket 简绍1 为什么用 websocket&#xff1f; 二、代码实现1、前端&#xff08;html&#xff09;1.1、无前端向后端发送消息1.2、有前端向…...

node使用高版本的oracledb导致连接oracle的Error: NJS-138异常

异常信息如下 Error: NJS-138: connections to this database server version are not supported by node-oracledb in Thin mode 我的oracle版本是11g&#xff0c;之前的使用正常&#xff0c;今天却报错了&#xff0c;显示不支持thin模式&#xff0c;后面回退版本就可以了。...

网站做数学题/网络的推广方式有哪些

dp概念&#xff1a;在整个数组或在固定大小的滑动窗口中找到总和或最大值或最小值的问题可以通过动态规划&#xff08;DP&#xff09;在线性时间内解决 题目&#xff1a; 给定一个无序的整数数组&#xff0c;找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18…...

培训网站系统建设/seo 培训教程

目录一、图文演示流程&#xff1a;二、具体思想&#xff1a;三、代码实现&#xff08;前端&#xff09;&#xff1a;四、代码实现&#xff08;后端&#xff09;&#xff1a;五、参考api&#xff1a;六、问题及解决&#xff1a;问题描述&#xff1a;解决方法&#xff1a;再次实现…...

贵州最好的网站建设推广公司/东莞疫情最新消息今天又封了

一、去掉图片间隙&#xff1a;hack1、img{ display&#xff1a;block&#xff1b; }hack2、将<div></div>与<img>写在同一行 二、ie6双倍浮向(双倍边距)出现情况&#xff1a;在浮动和外边距同事出现时会出现双向浮动。hack&#xff1a;给浮动元素添加&#x…...

宁德做网站/电商sem是什么意思

我想检查是否有任何用户有权下载任何文件.我有产品ID和用户ID,如何检查&#xff1f;我在google和woocommerce文档中进行了很多探索,但未找到任何解决方案.有什么帮助吗&#xff1f;提前致谢.解决方法:这是获取此信息的过程,您可以在php文件中的任何函数或挂钩函数中使用该信息.…...

openwrt wordpress/如何提高网站排名seo

Linux提供了大量的命令&#xff0c;利用它可以有效地完成大量的工 作&#xff0c;如磁盘操作、文件存取、目录操作、进程管理、文件权限设定等。所以&#xff0c;在Linux系统上工作离不开使用系统提供的命令。要想真正理解Linux系统&#xff0c; 就必须从Linux命令学起&#xf…...

阿里巴巴手工活加工平台/seo流量增长策略

写了个简单的代码&#xff0c;得分17/25 。 满分代码&#xff1a; 需要考虑好多的东西 #include <iostream> #include <vector> #include <algorithm> #include <string.h> using namespace std; int n; //有效位数string deal(string s, int&…...