草庐IT

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

北方的林檎 2023-03-28 原文

列表需求:
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~~~一个下拉刷新及上滑分页的微信小程序组件就完成啦~

有关微信小程序组件:列表(上滑加载、回到顶部)的更多相关文章

  1. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  2. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  5. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  6. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  7. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  8. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  9. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  10. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

随机推荐