美文网首页APP & program
微信小程序组件:列表(上滑加载、回到顶部)

微信小程序组件:列表(上滑加载、回到顶部)

作者: 牛会骑自行车 | 来源:发表于2022-04-28 13:31 被阅读0次

    列表需求:
    1.上滑加载(分页);
    2.回到顶部;
    3.列表组件下拉刷新。

    完成思路:
    1.加载数据一般有两种方式:一种是采用数组方法,concat或push或es6的扩展运算符,总之就是把后面加载的数据与前面的拼接到一起;另一种方式性能较好,采用给数据的某一项赋值的方式,就不会一次性setData太大的数据以至于会报错(代码中两种方案都有写,不仅组件中的写法不一样,用到的页面中写法也不同,需要注意)。
    2.回到顶部小箭头:页面滚动时监听容器的scrollTop,往下滑动时出现,接近0时消失;
    3.回到顶部:点击小箭头时,使容器的scrollTop为0。
    4.下拉刷新看scroll-view文档:
    https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html

    组件 👇
    html ↓

    <scroll-view 
      scroll-y 
      enhanced 
      bindscroll="scroll"
      bindscrolltolower="{{longPage?'':'moreData'}}" 
      scroll-top="{{scrollTop}}" 
      style="height: {{listHeight}}; "
      refresher-enabled 
      refresher-triggered="{{triggered}}" 
      bindrefresherrefresh="pullDownRefresh"
    >
      <!-- 
        ↑ 参数官网都给了解释,总之都有用到,尼萌自己去查吧~~
       -->
      <slot></slot>
      <!-- ↑ 列表插槽儿~页面中放置数据的容器 -->
      <image src="/images/common/icon_totop.png" class="icon_totop" wx:if="{{iconTotopShow}}" bindtap="handleTotop"></image>
      <!-- ↑ 回到顶部的小箭头 -->
    </scroll-view>
    

    css ↓

    .icon_totop {
      width: 72rpx;
      height: 80rpx;
      
      position: fixed;
      bottom: 30rpx;
      right: 20rpx;
    }
    

    js ↓

    // components/scrollList/list.js
    
    Component({
      properties: {
        // 是否分页:分页传false,不分页传true;默认需分页
        longPage: {
          type: Boolean,
          value: false 
        },
        // scroll-view的高度:官网有解释,如果使用scroll-view的话需要给其设置一个高度
        listHeight: String,
        // 接口相关的值
        interface: {
          type: Object,
            value: () => {
              return {
                url: "", // 接口地址
                params: {}, // 接口所需参数
                method: "" // 请求方法
              }
            }
        },
        // 下拉刷新所需的参数
        refresh: Boolean
      },
      data: {
        maxPage: null, // 最多页数
        data: [],
        iconTotopShow: false, // 回到顶部的图标显隐参数
        scrollTop: 0, // scroll-view滚动距离
        triggered: false, // 下拉刷新的提示
      },
      methods: {
        getData() {
          wx.showLoading({
            title: "加载中..."
          })
          let {
            url,
            method,
            params
          } = this.data.interface;
          // wx.httpWithoutToken是已经封装好的调取接口的方法,用wx.request也可以,用一样参数即可
          wx.httpWithoutToken(url, params, method).then(res => {
            if (res.code === 200 && res.success) {
              // 最大页码 = 数据总数 / 每页数据数
              let maxPage = res.totalCount / this.data.interface.params.pageSize;
              // 方法1:用数组方法先拼接再传值
              // let data = [...this.data.data,...res.content];
              // 方法2:只传递接口当前页的返回值
              let data = res.content;
    
              this.setData({
                maxPage,
                data
              })
              // 给父页面传值
              this.triggerEvent("update", {
                num: this.data.interface.params.pageNum, // 方法2中所需参数
                data
              })
            } else {
              wx.showToast({
                title: "暂无数据",
                icon: "none"
              })
            }
            wx.hideLoading();
            this.setData({
              triggered: false
            })
          })
        },
        moreData() {
          // 当前页码
          let num = this.data.interface.params.pageNum;
          // 最大页码存在且当前页码 >= 最大页码则数据全部展示完毕
          if (this.data.maxPage && num >= this.data.maxPage) {
            wx.showToast({
              title: "暂无数据",
              icon: "none"
            })
            return;
          }
          // 进行到这一步说明还可以继续请求,则页码+1
          num++;
          this.setData({
            "interface.params.pageNum": num
          })
          this.getData();
        },
        scroll(e) {
          // scroll-view的滚动距离
          let num = e.detail.scrollTop;
          // 如果这个距离小于一定的数据就让图标消失,反之图标出现
          let iconTotopShow = num <= 10 ? false : true;
          this.setData({
            iconTotopShow
          })
        },
        handleTotop() {
          // 通过给scroll-view的scrollTop赋值来让页面回到顶部
          this.setData({
            scrollTop: 0
          })
        }
      },
      pageLifetimes: {
        show() {
          this.getData();
        }
      },
      pullDownRefresh() {
        this.setData({
          ["interface.params.pageNum"]: 1,
          triggered: true
        })
        this.triggerEvent("clearList")
      },
      observers: {
        "refresh": function (val) {
          // observers会比show()生命周期先行
          // 通过判断有没有传入的interface来确定要不要调取接口
          if (JSON.stringify(this.data.interface) === '{}') return;
          // 初始化页面请求参数
          this.setData({
            'interface.params.pageNum': 1
          })
          // 再调取接口
          this.getData();
        }
      }
    })
    

    用到的页面 👇
    html ↓

    <!--views/list/list.wxml-->
    
    <list interface="{{info}}" bindupdate="getData" refresh="{{refresh}}" listHeight="80vh">
    
      <view class="row bg_w" wx:for="{{list}}" wx:key="index">
        <view>{{item.name}}</view>
        <view>{{item.code}}</view>
      </view>
    
    </list>
    

    js文件 ↓

    // views/list/list.js
    Page({
      data: {
        info: {},
        list: [],
        refresh: false
      },
      initPage() {
        let info = {
          url: "selectOrder",
          method: "GET",
          params: {
            pageNum: 1,
            pageSize: 2
          }
        }
        this.setData({
          info
        })
      },
      getData(e) {
        // 方法1
        // this.setData({
        //   list: e.detail.data
        // })
    
        // 方法2
        let list = e.detail.data; // 组件里传出来的当前页数据
        let num = (e.detail.num - 1) * this.data.info.params.pageSize; 
        // 采用循环的方法给数组的每一项赋值
        list.forEach((item,index) => {
          this.setData({
            [`list[${num+index}]`]: item
          })
        })
      },
      onLoad: function (options) {
        this.initPage();
      },
      onPullDownRefresh: function() {
        // 下拉刷新时给refresh重新赋值
        this.setData({
          refresh: !this.data.refresh
        })
      }
    })
    

    还有一步引用组件,在当前页的json文件也可,app.json文件中全局引用也可~

    tada~~~一个下拉刷新及上滑分页的微信小程序组件就完成啦~

    相关文章

      网友评论

        本文标题:微信小程序组件:列表(上滑加载、回到顶部)

        本文链接:https://www.haomeiwen.com/subject/oyrqyrtx.html