微信小程序实现上拉加载更多

一、前情提要

  1. 微信小程序中实现上拉加载更多,其实就是pc端项目的分页。
  2. 使用的是scroll-view,scroll-view详情在微信开发文档/开发/组件/视图容器中。
  3. 每次上拉,就是在原有数据基础上,拼接/合并上本次上拉请求得到的数据。
  4. 这里采用的是concat,concat 是数组对象的一个方法,用于合并两个或多个数组,生成一个新的数组。这个方法不会修改原始数组,而是返回一个新的数组
  5. concat使用示例如下:
// 示例数组
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [7, 8, 9];

// 使用concat合并数组
const mergedArray = array1.concat(array2, array3);

// 打印结果
console.log("原始数组1: ", array1);
console.log("原始数组2: ", array2);
console.log("原始数组3: ", array3);
console.log("合并后的数组: ", mergedArray);

//输出结果应为:
原始数组1:  [1, 2, 3]
原始数组2:  [4, 5, 6]
原始数组3:  [7, 8, 9]
合并后的数组:  [1, 2, 3, 4, 5, 6, 7, 8, 9]

二、代码示例(1)不使用onReachBottom

  1. index.wxml
//1、scroll-y 允许纵向滚动
//2、lower-threshold="100px" 距底部/右边多远(100px)时,触发 scrolltolower 事件
//3、scroll-top="{{topHeight}}px" 设置竖向滚动条位置
<view class="box">
	<!-- 列表 -->
	<scroll-view scroll-y lower-threshold="100px" bindscrolltolower="scrollToLower" style="height: 80vh;" scroll-top="{{topHeight}}px" class="scrView">
		<view class="listBox" wx:for="{{groupData}}" wx:key="id">
			<view class="name">{{item.name}}</view>
			<view class="phone">{{item.mobile}}</view>
			<image src="../../image/icon/bj.png" bindtap="editRecipient" data-item="{{item}}" class="mini-btn" />
			<image src="../../image/icon/sc.png" bindtap="deleteRecipient" data-id="{{item.id}}" class="mini-btn2" />
		</view>
		<view style="text-align: center;">
            <view wx:if="{{loading}}">加载中...</view>
            <view wx:if="{{noMore && !noData}}">没有更多了</view>
            <view wx:if="{{noData}}">暂无数据</view>
        </view>
	</scroll-view>
</view>
  1. index.js
Page({
  data: {
   loading: false, //加载更多的loading
   noMore: false,   //没有更多了
   noData:false, //暂无数据
   isPage:false, // 是否需要分页 ispage的作用 进页面首次在onLoad中调用时,不需要合并数据
   page:1,
   limit:5,
   topHeight:0, 
 },
 /**
  * 生命周期函数--监听页面加载
  */
 onLoad(options) {
   this.getContactList()
 },
 // restore函数的作用,当业务有搜索、删除、新增、编辑等操作时,需要还原对应参数状态。
 // 初始化数据
 restore(){
   this.setData({
     loading: false, //加载更多的loading
     noMore: false,   //没有更多了
     noData:false,
     isPage:false,
     page:1,
     limit:5,
     topHeight:0, 
   })
 },
 getContactList(isPage){
   let params = {
     page:this.data.page,
     limit:this.data.limit,
     tid: this.data.inquirFform.tagID
   }
   req.group.contactList(params).then((res) =>{

     if (isPage) {
       // 下一页数据拼接在原始数据后面
       this.setData({
         groupData: this.data.groupData.concat(res.data.list),
         loading: false
       })
     } else {
       this.setData({
         groupData: res.data.list,
         loading: false
       })
     }
     //如果返回的数据为空,那么就没有下一页了
     if (res.data.list.length == 0 && this.data.isPage) {
       this.setData({
         noMore: true
       })
     }
     if (res.data.list.length == 0 && !this.data.isPage) {
       this.setData({
         noMore: true,
         noData:true
       })
     }
   })
 },
 // 下滑到底部触发
 scrollToLower(){
   if (!this.data.loading && !this.data.noMore) {
     this.setData({
       loading: true,
       page: this.data.page + 1,
       isPage:true
     })
     this.getContactList(this.data.isPage)
   }
 },
})

示例图片如下:
请添加图片描述

三、代码示例(2)使用onReachBottom(1)

onReachBottom:监听用户上拉触底事件。
可以在app.json的window选项中或页面配置中设置触发距离onReachBottomDistance。
在触发距离内滑动期间,本事件只会被触发一次。

  • 每次请求数据时候,在底部提示加载中

  • 当请求完全部数据时,在底部提示 没有更多数据了,
    后端返回数据总条数 如下.js文件中的 total 判断 每次请求时判断前端拿到的总数据的length == total,若是等于 则显示 没有更多数据了,并且 再次上拉时,不进行数据的请求。

  • 前端传 page 当前页 每次请求 page + 1
    limit:没有数量 前端自己写个固定值就行
    业务参数:若列表支持查询搜索等,传自己的业务数据

  • 后端返回 total:总数据条数
    data:[] 对应的数据列表

  • 有导航切换的需要注意,切换导航后先重置 加载中提示,没有更多数据提示,page等参数后,在请求数据

、、、
1、wxml

<view class="content">
    <view class="body">
      <view class="box" wx:for="{{proArr}}" wx:key="_id">
        <xzs-product-item item="{{item}}"></xzs-product-item>
      </view>
    </view>
    <view class="loadOut">
      <van-loading size="24px" wx:if="{{loading}}">加载中...</van-loading>
      <view class="noData" wx:if="{{isData}}">没有更多数据了~</view>
    </view>
</view>
```';

3、.js


Page({

  /**
 * 页面的初始数据
   */
  data: {
    navActive:0,
    navArr:[],

    proArr:[],
    page:1,
    limit:10,
    loading:false,
    isData:false
  },

  /**
 * 生命周期函数--监听页面加载
   */
  async onLoad(options) {
    let {idx} = options;    
    await this.getNavList(); 
    if(idx){
      this.navChange(idx);
    }else{
      navid = this.data.navArr[0]._id;
      this.getProductList();
    }
  },
  //获取产品列表
  getProductList(){
    this.setData({
      loading:true
    })
    queryProduct({
      navid:navid,
      page:this.data.page,
      limit:this.data.limit
    }).then(res=>{   
      let oldArr= this.data.proArr;
      let newArr=oldArr.concat(res.data)   
      console.log(res);
      this.setData({
        proArr:newArr,
        loading:false
      })
      if(res.total == this.data.proArr.length){
        this.setData({
          isData:true
        })
      }
    })
  },

  //导航条切换事件
  navChange(e){    
    let index= e?.detail?.index ?? e;
    navid = this.data.navArr[index]._id
    this.setData({
      proArr:[],
      loading:false,
      isData:false,
      page:1,
      navActive:Number(index)
    })    
    this.getProductList();
  },
  /**
 * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    if(this.data.isData) return;
    this.setData({
      page:this.data.page + 1})
    this.getProductList()
  },
})

四、代码示例(2)使用onReachBottom(2)

  • 这个同 三、代码示例(2)类似,只不过是请求时传递给后端的参数不同
  • 前端传 size: 就是列表数据的长度,初始是0。例如:第一次,请求得到数据长度为5 ,那么上拉数据请求时候,size就传5,再次上拉,合并数据后长度为10,下次上拉请求就传10

1、.wxml

<view class="content">
    <view class="body">
      <view class="box" wx:for="{{proArr}}" wx:key="_id">
        <xzs-product-item item="{{item}}"></xzs-product-item>
      </view>
    </view>
    <view class="loadOut">
      <van-loading size="24px" wx:if="{{loading}}">加载中...</van-loading>
      <view class="noData" wx:if="{{isData}}">没有更多数据了~</view>
    </view>
</view>

2、.js

Page({

  /**
   * 页面的初始数据
   */
  data: {
    navActive:0,
    navArr:[],
    proArr:[],
    loading:false,
    isData:false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  async onLoad(options) {
      this.getProductList();
  },
  //获取产品列表
  getProductList(s=0){
    this.setData({
      loading:true
    })
    queryProduct({
      navid:navid,
      size:s
    }).then(res=>{   
      let oldArr= this.data.proArr;
      let newArr=oldArr.concat(res.data)   
      console.log(res);
      this.setData({
        proArr:newArr,
        loading:false
      })
      if(res.total == this.data.proArr.length){
        this.setData({
          isData:true
        })
      }
    })
  },

  //导航条切换事件
  navChange(e){    
    let index= e?.detail?.index ?? e;
    navid = this.data.navArr[index]._id
    this.setData({
      proArr:[],
      loading:false,
      isData:false,
      navActive:Number(index)
    })    
    this.getProductList();
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    if(this.data.isData) return;
    this.getProductList(this.data.proArr.length)
  }
})

三和四几乎一样,就看前后端怎么约定的穿什么数据,返回什么数据

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现微信小程序上拉加载更多数据,你可以通过以下步骤实现: 1. 在 wxml 文件中添加一个 scroll-view 组件,并设置其 scroll-into-view 属性为一个变量,用于记录当前滚动到的位置。 2. 在 js 文件中,定义一个变量 page,表示当前加载的页数,初始值为 1。 3. 在 scroll-view 组件上绑定一个 scrolltolower 事件,当滚动到底部时触发该事件。 4. 在 scrolltolower 事件中,发送请求获取下一页数据,并将 page 加 1。 5. 将获取到的数据添加到原有数据列表中。 6. 在获取数据之前,显示一个 loading 提示。 7. 在请求结束后,隐藏 loading 提示,并更新 scroll-into-view 属性,将页面滚动到数据的最后一项。 以下是一个简单的示例代码: ``` // wxml 文件 <scroll-view scroll-into-view="{{scrollIntoView}}" scroll-y="true" bindscrolltolower="loadMoreData"> <view wx:for="{{dataList}}" wx:key="{{index}}">{{item}}</view> </scroll-view> // js 文件 Page({ data: { dataList: [], // 数据列表 page: 1, // 当前页数 scrollIntoView: '', // 当前滚动到的位置 loading: false // 是否正在加载数据 }, onLoad: function () { this.loadData() }, // 加载第一页数据 loadData: function () { // 显示 loading 提示 wx.showLoading({ title: '加载中', }) // 发送请求获取数据 wx.request({ url: 'https://example.com/api/data?page=1', success: res => { // 隐藏 loading 提示 wx.hideLoading() // 更新数据列表 this.setData({ dataList: res.data.data }) } }) }, // 加载更多数据 loadMoreData: function () { // 如果正在加载数据,则不处理 if (this.data.loading) { return } // 显示 loading 提示 wx.showLoading({ title: '加载中', }) // 发送请求获取数据 wx.request({ url: 'https://example.com/api/data?page=' + (this.data.page + 1), success: res => { // 隐藏 loading 提示 wx.hideLoading() // 更新数据列表 this.setData({ dataList: this.data.dataList.concat(res.data.data), page: this.data.page + 1, scrollIntoView: 'item-' + (this.data.dataList.length - 1) // 将页面滚动到最后一项 }) }, complete: () => { // 标记数据加载完成 this.setData({ loading: false }) } }) // 标记正在加载数据 this.setData({ loading: true }) } }) ``` 在上述示例中,我们使用了 wx.showLoading 和 wx.hideLoading 方法来显示和隐藏 loading 提示。注意,在请求结束后,需要在 complete 回调函数中调用 setData 方法,以更新 loading 变量的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值