前言

本文介绍了小程序和H5分页加载功能的实现方案。

主要包含:

1) 配置页面下拉刷新和上拉加载功能;

2) 实现onReachBottom触底事件处理,通过页码控制数据请求;

3) 使用防抖机制避免重复请求,通过isfinish标志位控制加载状态;

4) 数据请求函数getCommodityList的实现,处理分页参数和响应数据;

5) 前端页面展示,包括滚动视图、数据列表和加载状态提示;

6) 优化方案包括防抖处理、加载状态管理和错误处理等。整个方案实现了流畅的分页加载体验,具备良好的性能和用户体验。


小程序


配置

{
						"path": "list/course-list",
						"style": {
							"navigationBarTitleText": "课程列表",
							"enablePullDownRefresh": true,
							"onReachBottomDistance": 150
						}
					}

上拉拉触底钩子

onReachBottom() {
			var that = this;
			if (that.groupPage * that.showNo - that.groupTotal < 0) {
				setTimeout(function () {
					that.groupPage += 1;
					that.getCommodityList();//请求下页数据
				}, 200);
			} else {
				this.isfinish = true;
				console.log("数据已经加载完成")
			}
		},

data值

data() {
		return {
			imgBaseWebUrl: this.$imgBaseWebUrl,
			serverFileUrl: app.globalData.ossFileServer,
			loading: '加载中',
			shopList: [],
			flowList: [],
			leftList: [],
			dictClassifyId: "",
			searchText: '',//搜索关键字
			groupPage: 1, //列表部分当前页码
			groupTotal: 0, //列表部分总页码
			showNo: 10,//每页显示条数
			isfinish: false,//列表数据是否加载完成
			reqIng: true,//数据请求中
			
		};
	

getCommodityList请求数据:

//获取所有商品
		getCommodityList: function () {
			let that = this;
			let url = "/classSchedule/page";
			that.reqIng = true;
			that.isfinish = false;
			let params;
			if(this.searchText){
				params={
					page: that.groupPage,
					title:this.searchText
				}
				
			}else{
				params={
					page: that.groupPage
				}
			}
			
			// console.log("当前请求页码", that.groupPage)
			
			this.$http
				.post(url, params)
				.then((res) => {
					uni.hideLoading();
					console.log('后端', res);
					if (res.code == 200) {
							that.flowList=res.rows;
				

							console.log('取到的数据', that.flowList)

						if (that.showNo >= res.total) {//只有一页数据
							that.isfinish = true;
						}

					} else {
						uni.showToast({
							title: res.message,
							icon: "none",
						});
					}

					that.reqIng = false;
				}).catch((i) => {
				}).finally(() => {
					uni.hideLoading();
				});
		},


H5


view

<template>
  <view class="container">
    <!-- 可滚动视图 -->
    <scroll-view
      scroll-y
      :style="{ height: windowHeight + 'px' }"
      @scrolltolower="loadMore"
    >
      <!-- 数据列表 -->
      <view v-for="(item, index) in listData" :key="index" class="item">{{ item }}</view>
      
      <!-- 加载状态提示 -->
      <view v-if="isLoadingMore" class="loading">加载中...</view>
      <view v-if="hasMore === false" class="no-more">没有更多了</view>
    </scroll-view>
  </view>
</template>

js

export default {
  data() {
    return {
      listData: [],           // 存储列表数据
      page: 1,                // 当前页码
      isLoadingMore: false,   // 是否正在加载中
      hasMore: true,          // 是否还有更多数据
      windowHeight: uni.getSystemInfoSync().windowHeight // 屏幕高度
    }
  },
  created() {
    this.getListData() // 初始化加载第一页数据
  },
  methods: {
    // &#128293; 核心:加载更多数据
    async loadMore() {
      if (!this.hasMore || this.isLoadingMore) return // 防抖:避免重复请求
      
      this.isLoadingMore = true
      try {
        const newData = await this.fetchData({ page: this.page + 1 })
        if (newData.length > 0) {
          this.listData = [...this.listData, ...newData]
          this.page++
        } else {
          this.hasMore = false // 无更多数据
        }
      } catch (error) {
        console.error('加载失败:', error)
        uni.showToast({ title: '加载失败', icon: 'none' })
      } finally {
        this.isLoadingMore = false
      }
    },
    // 模拟API请求(实际替换为你的接口)
    fetchData({ page }) {
      return new Promise(resolve => {
        setTimeout(() => {
          // 模拟分页数据(每页5条)
          const startIndex = (page - 1) * 5 + 1
          const endIndex = page * 5
          const mockData = Array(5).fill().map((_, i) => `第${page}页-条目${startIndex + i}`)
          resolve(mockData)
        }, 800) // 模拟网络延迟
      })
    },
    // 可选:下拉刷新重置数据
    onPullDownRefresh() {
      this.page = 1
      this.listData = []
      this.hasMore = true
      this.getListData()
      uni.stopPullDownRefresh() // 停止刷新动画
    },
    getListData() {
      this.fetchData({ page: this.page }).then(data => {
        this.listData = data
        this.page++
      })
    }
  }
}

css

.container {
  width: 100%;
  height: 100vh;
}
.item {
  padding: 20rpx;
  border-bottom: 1px solid #f0f0f0;
  text-align: center;
}
.loading {
  text-align: center;
  padding: 20rpx;
  color: #999;
}
.no-more {
  text-align: center;
  padding: 20rpx;
  color: #ccc;
  font-size: 28rpx;
}

H5下拉生命周期,阻止加载


 onPullDownRefresh() {
    
    uni.stopPullDownRefresh();
  },

H5上拉加载优化


防抖

 loadMore() {
      let that = this;
			console.log("上拉数据加载")
          if (this.pageNo < this.pages) {
            console.log("数据更新");
            if(this.isfinish==true) return;
            this.isfinish=true;// 防抖:避免重复请求
            setTimeout(function () {
                that.pageNo += 1;
                that.getListData(that.pageNo, false);

            }, 200);
          } else {
            console.log("当前已经是全部数据")
       }

    },

请求函数

getListData(pageNo, override) {
      this.isfinish = false;
      uni.showLoading({
        title: "加载中...",
      });
      let { residentList } = this;
      let param = {
        page: pageNo,
        per_page: 10,
        no_normal: this.noNormal,
        ...this.params,
      };
      this.$http
        .get(this.$api.residentPage, param)
        .then((res) => {
          // uni.hideLoading();
          let { objects, total_pages } = res;
          let objitem = objects.map((item) => {
            return {
              ...item,
              username: [aesDecrypt(item.username)].toString(),
              phone: [aesDecrypt(item.phone)].toString(),
            };
          });
          // this.residentList = override ? objects : residentList.concat(objects);
          this.residentList = override ? objitem : residentList.concat(objitem);
          this.pageNo = pageNo;
          this.pages = total_pages;
          
        })
        .finally(() => {
          uni.hideLoading();
        });
    },

data内容

      isLoadingMore: false,   // 是否正在加载中
      hasMore: true,          // 是否还有更多数据
      windowHeight: uni.getSystemInfoSync().windowHeight, // 屏幕高度
      pages: 1,
      pageNo: 1,
      isfinish: false,//列表数据是否加载完成

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐