• 微信小程序中如何实现分页下拉加载?(附源码)


    转眼间坚持写教你微信小程序系列已经有十节系列课程了,每天的工作压力繁重,小女子也不知道自己还能坚持这样的系列教程多久。只希望每篇教程真的对大家有帮助。这节课我们要介绍的就是如何实现分页的下拉加载,我们先来看效果图
     

    1
    2
    3
    4
    5
    6
    7
    8
    <view class="copyright">
        <view class="copyright_item">CopyRight:All Right Reserved</view>
        <view class="copyright_item">原创作者:51小程序</view>
        <view class="copyright_item">微信小程序开发者社区</view>
        <view class="copyright_item">HTML51.COM</view>
        <view class="copyright_item"><image class="img" src="../copyright/image/logo.png"/></view>
        <view class="goto_counter"><button type="default" bindtap="goto_counter">点击进入下拉加载演示页面</button></view>
    </view>
    当用户打开一个页面时,假设后台数据量庞大时,一次性地返回所有数据给客户端,页面的打开速度就会有所下降,而且用户只看上面的内容而不需要看后面的内容时,也浪费用户流量,基于优化的角度来考虑,后台不要一次性返回所有数据,当用户有需要再往下翻的时候,再加载更加数据出来。
     
    业务需求:
    列表滚动到底部时,继续往上拉,加载更多内容
     
    必备参数:
    (1)pageindex: 1 //第几次加载
    (2)callbackcount: 15 //需要返回数据的个数
    其他参数:
    根据接口的所需参数
     
    实现原理:
    当第一次访问接口时,传递2个必备参数(第1次加载,需要返回数据的个数为15个),和其他参数(需要搜索的字符串)给后台,后台返回第一次数据过来。在请求成功的的回调函数中,判断返回的数据是否>0,是,则取出数据,渲染视图层,并把“上拉加载”显示在列表底部;否,则没有数据可取,并把“没有更多”显示在列表底部,同时把“上拉加载”隐藏掉。
    当用户已经滚动到列表底部(这里使用到小程序提供的scroll-view组件的bindscrolltolower事件),触发bindscrolltolower事件,参数pageindex+1,再把2个必备参数(第2次加载,需要返回数据的个数为15个)和其他参数(需要搜索的字符串)给后台,后台把其余的数据返回给前台,前台在原来数据的基础上添加数据


    主要的页面结果如下:
    1.index.wxml

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <view class="search"> 
      <view class="search-bar"> 
        <view class="search-wrap"> 
            <icon type="search" size="16" class="icon-search" /> 
            <input type="text" placeholder="请输入搜索内容" class="search-input" name="searchKeyword" bindinput="bindKeywordInput" value="{{searchKeyword}}" /> 
        </view> 
        <view class="search-cancel" bindtap="keywordSearch">搜索</view> 
      </view> 
      <view class="search-result"> 
        <scroll-view scroll-y="true" bindscrolltolower="searchScrollLower"> 
          <view class="result-item" wx:for="{{searchSongList}}" wx:key="unique"  data-data="{{item}}" > 
            <view class="icon{{item.isonly=='0' ? ' nocopyright' : ''}}"></view> 
            <text class="title">{{item.songname}}</text> 
            <view class="subtitle"> 
              <text wx:for="{{item.singer}}" wx:key="unique">{{item.name}}</text> 
            </view> 
          </view> 
          <view class="loading" hidden="{{!searchLoading}}">正在载入更多...</view> 
          <view class="loading complete" hidden="{{!searchLoadingComplete}}">已加载全部</view> 
        </scroll-view>   
      </view> 
    </view>



    2.index.wxss

    001
    002
    003
    004
    005
    006
    007
    008
    009
    010
    011
    012
    013
    014
    015
    016
    017
    018
    019
    020
    021
    022
    023
    024
    025
    026
    027
    028
    029
    030
    031
    032
    033
    034
    035
    036
    037
    038
    039
    040
    041
    042
    043
    044
    045
    046
    047
    048
    049
    050
    051
    052
    053
    054
    055
    056
    057
    058
    059
    060
    061
    062
    063
    064
    065
    066
    067
    068
    069
    070
    071
    072
    073
    074
    075
    076
    077
    078
    079
    080
    081
    082
    083
    084
    085
    086
    087
    088
    089
    090
    091
    092
    093
    094
    095
    096
    097
    098
    099
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    page{ 
      display: flex; 
      flex-direction: column
      height: 100%; 
    } 
       
    /*搜索*/ 
    .search{ 
      flex: auto; 
      display: flex; 
      flex-direction: column
      background: #fff; 
    } 
    .search-bar{ 
      flex: none; 
      display: flex; 
      align-items: center
      justify-content: space-between
      padding: 20rpx; 
      background: #f4f4f4; 
    } 
    .search-wrap{ 
      position: relative; 
      flex: auto; 
      display: flex; 
      align-items: center
      height: 80rpx; 
      padding: 0 20rpx; 
      background: #fff; 
      border-radius: 6rpx; 
    } 
    .search-wrap .icon-search{ 
      margin-right: 10rpx; 
    } 
    .search-wrap .search-input{ 
      flex: auto; 
      font-size: 28rpx; 
    } 
    .search-cancel{ 
      padding: 0 20rpx; 
      font-size: 28rpx; 
    } 
       
    /*搜索结果*/ 
    .search-result{ 
      flex: auto; 
      position: relative; 
    } 
    .search-result scroll-view{ 
      position: absolute; 
      bottom: 0
      left: 0
      right: 0
      top: 0
    } 
    .result-item{ 
      position: relative; 
      display: flex; 
      flex-direction: column
      padding: 20rpx 0 20rpx 110rpx; 
      overflow: hidden
      border-bottom: 2rpx solid #e5e5e5; 
    } 
       
    .result-item .media{ 
      position: absolute; 
      left: 16rpx; 
      top: 16rpx; 
      width: 80rpx; 
      height: 80rpx; 
      border-radius: 999rpx; 
    } 
    .result-item .title, 
    .result-item .subtitle{ 
      overflow: hidden
      text-overflow: ellipsis; 
      white-space: nowrap; 
      line-height: 36rpx; 
    } 
    .result-item .title{ 
      margin-bottom: 4rpx; 
      color: #000; 
    } 
    .result-item .subtitle{ 
      color: #808080; 
      font-size: 24rpx; 
    } 
    .result-item:first-child .subtitle text{ 
      margin-right: 20rpx; 
    } 
    .result-item:not(:first-child) .subtitle text:not(:first-child):before{ 
      content: '/'; 
      margin: 0 8rpx; 
    } 
    .loading{ 
      padding: 10rpx; 
      text-align: center
    } 
    .loading:before{ 
      display: inline-block; 
      margin-right: 5rpx; 
      vertical-align: middle
      content: ''; 
      width: 40rpx; 
      height: 40rpx; 
      background: url(../index/images/icon-loading.png) no-repeat
      background-size: contain
      animation: rotate 1s linear infinite; 
    } 
    .loading.complete:before{ 
      display: none; 
    } 



    3.index.js

     
     
     
     
     
     
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    var util = require('../../utils/util.js') 
    Page({ 
      data: { 
        searchKeyword: '',  //需要搜索的字符 
        searchSongList: [], //放置返回数据的数组 
        isFromSearch: true,   // 用于判断searchSongList数组是不是空数组,默认true,空的数组 
        searchPageNum: 1,   // 设置加载的第几次,默认是第一次 
        callbackcount: 15,      //返回数据的个数 
        searchLoading: false, //"上拉加载"的变量,默认false,隐藏 
        searchLoadingComplete: false  //“没有数据”的变量,默认false,隐藏 
      }, 
      //输入框事件,每输入一个字符,就会触发一次 
      bindKeywordInput: function(e){ 
        console.log("输入框事件") 
        this.setData({ 
          searchKeyword: e.detail.value 
        }) 
      }, 
      //搜索,访问网络 
      fetchSearchList: function(){ 
        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) 
          //判断是否有数据,有则取数据 
          if(data.data.song.curnum != 0){ 
            let searchList = []; 
            //如果isFromSearch是truedata中取出数据,否则先从原来的数据继续添加 
            that.data.isFromSearch ? searchList=data.data.song.list : searchList=that.data.searchSongList.concat(data.data.song.list) 
            that.setData({ 
              searchSongList: searchList, //获取数据数组 
              zhida: data.data.zhida, //存放歌手属性的对象 
              searchLoading: true   //"上拉加载"的变量设为false,显示 
            })
          //没有数据了,把“没有数据”显示,把“上拉加载”隐藏 
          }else{ 
            that.setData({ 
              searchLoadingComplete: true, //把“没有数据”设为true,显示 
              searchLoading: false  //"上拉加载"的变量设为false,隐藏 
            })
          } 
        }) 
      }, 
      //点击搜索按钮,触发事件 
      keywordSearch: function(e){ 
        this.setData({   
          searchPageNum: 1,   //第一次加载,设置1 
          searchSongList:[],  //放置返回数据的数组,设为空 
          isFromSearch: true,  //第一次加载,设置true 
          searchLoading: true,  //"上拉加载"的变量设为true,显示 
          searchLoadingComplete:false //把“没有数据”设为false,隐藏 
        }) 
        this.fetchSearchList()
      }, 
      //滚动到底部触发事件 
      searchScrollLower: function(){ 
        let that = this; 
        if(that.data.searchLoading && !that.data.searchLoadingComplete){ 
          that.setData({ 
            searchPageNum: that.data.searchPageNum+1,  //每次触发上拉事件,把searchPageNum+1 
            isFromSearch: false  //触发到上拉事件,把isFromSearch设为为false 
          })
          that.fetchSearchList()
        } 
      } 
    })
    源码下载地址:http://bbs.html51.com/t-1450-1-1/
  • 相关阅读:
    Asp.Net下的DataGrid的多层表头(转自csdn)
    C#中使用DirectX编程 (转)
    Factory Method来实现数据库操作的类 (转) 原文:冷风.NET
    (转)关于定时器,介绍得很好!
    (原创)如何让web页面产生服务器数据返回后仍然能够保留到用户输入的位置!
    最近加入了控件开发团队,发现一些基础的东西,转发上来方便大家学习(转)
    中国共享软件走向国际指南(转,有感而发!)
    水晶报表官方实例大全 (转)
    用VS.NET2003制作WEB应用程序的安装包 (转)
    开发 Windows Mobile 应用程序: FAQ(最近买了ppc,正好打算学习开发使用。)
  • 原文地址:https://www.cnblogs.com/thebeauty/p/6599612.html
Copyright © 2020-2023  润新知