微信小程序下拉刷新上拉加载

Posted 优小U

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序下拉刷新上拉加载相关的知识,希望对你有一定的参考价值。

微信小程序官方没有给出具体的下拉刷新和上拉加载组件,我们可以基于小程序原生组件scroll-view的扩展与封装,实现简单的上拉加载、下拉刷新组件。

1. 封装组件

// components/customPullDown/index.js
Component(
	options: 
		multipleSlots: true
	,
	properties: 
		changeBoundaryThreshold: 
			type: Number,
			default: 45
		,
	,

	observers: 
		'changeBoundaryThreshold': function (val) 
			this.setData(
				changeBoundary: val
			)
		
	,
	data: 
		refresherTriggered: false,
		changeBoundary: 45
	,
	methods: 
		onReachBottom (event) 
			this.triggerEvent('onReachBottom')
		,
		onRefresherRestore (event) 
			this.triggerEvent('onRefresherRestore')
		,
		onRefresherAbort (event) 
			this.triggerEvent('onRefresherAbort')
		,
		onPullDownRefresh (event) 
			this.setTriggerStatus(true)
			setTimeout(() => 
				this.setTriggerStatus(false)
			, 1000)
		,
		setTriggerStatus (bool) 
			this.setData(
				refresherTriggered: bool
			)
			this.triggerEvent(bool ? 'onPullDownRefreshStart' : 'onPullDownRefreshEnd')
		
	
)

// components/customPullDown/index.json

    "component": true,
    "usingComponents": 

<!-- components/customPullDown/index.wxml -->
<wxs module="pullDown" src="./pullDown.wxs"></wxs>
<view class="pull-down">
  <scroll-view
    refresher-enabled
    scroll-y
    scroll-with-animation
    refresher-default-style="none"
    refresher-triggered="refresherTriggered"
    bindrefresherpulling="pullDown.onContentPull"
    bindrefresherrestore="pullDown.onRestore"
    bindrefresherabort="pullDown.onAbort"
    bindrefresherrefresh="pullDown.onRefresh"
    bindscrolltolower="onReachBottom"
    class="scroll-box"
  >
    <view slot="refresher" class="custom-refresh-zone" data-threshold="changeBoundary">
      <view class="refresh-before-trigger">
        <view class="custom-refresh-zone-tips-loading">继续下拉刷新</view>
      </view>
      <view class="refresh-after-trigger">
        <view class="custom-refresh-zone-tips-loading">释放刷新</view>
      </view>
      <view class="refresh-loading">
        <view class="custom-refresh-zone-tips-loading">加载中...</view>
      </view>
    </view>
    <view>
      <view name="refresh-animation"></view>
      <slot name="content"></slot>
    </view>
  </scroll-view>
</view>
/* components/customPullDown/index.wxss */
.pull-down
  width: 100%;
  height: 100%;
  position: relative;

.scroll-box
  width: 100%;
  height: 100%;

.custom-refresh-zone
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: center;

.refresh-loading
  width: 100%;


.custom-refresh-zone .refresh-before-trigger,
.custom-refresh-zone .refresh-after-trigger
  display: none;

.custom-refresh-zone.refresher-before .refresh-before-trigger,
.custom-refresh-zone.refresher-after .refresh-after-trigger
  width: 100%;
  display: block;

.custom-refresh-zone.refresher-before .refresh-loading,
.custom-refresh-zone.refresher-after .refresh-loading
  display: none;

.custom-refresh-zone-tips-loading
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 100%;
  color: #bbb;
  font-size: 26rpx;
  padding: 10rpx;

.custom-refresh-zone-tips-loading.white 
  color: #fff;

/* components/customPullDown/pullDown.wxs */
var refresherBefore = 'refresher-before'
var refresherAfter = 'refresher-after'

function getComponent(name, selector) 
  return function(instance) 
    var state = instance.getState()
    return state[name] || (state[name] = instance.selectComponent(selector))
  

var getCustomRefresher = getComponent('customRefresher', '.custom-refresh-zone')

module.exports = 
  onContentPull: function (event, ownerInstance) 
    var scrollY = event.detail.dy // 滚动距离
    // 根据滚动距离切换状态
    var customRefresher = getCustomRefresher(ownerInstance)
    var threshold = customRefresher.getDataset().threshold
    var isLargerThanTriggerThreshold = scrollY > threshold
    customRefresher
      .addClass(isLargerThanTriggerThreshold ? refresherAfter : refresherBefore)
      .removeClass(isLargerThanTriggerThreshold ? refresherBefore : refresherAfter)
  ,
  onRestore: function (event, ownerInstance) 
    ownerInstance.callMethod('onRefresherRestore', event)
  ,
  onAbort: function (event, ownerInstance) 
    ownerInstance.callMethod('onRefresherAbort', event)
  ,
  onRefresh: function (event, ownerInstance) 
    var customRefresher = getCustomRefresher(ownerInstance)
    customRefresher.removeClass(refresherAfter, refresherBefore)
    ownerInstance.callMethod('onPullDownRefresh', event)
  ,

2. 业务页面使用

<!-- pages/service/service.wxml -->
<view style="height: 500rpx;border: 1px solid red;">
  <custom-pull-down 
    class="custom-pull-down" 
    bind:onReachBottom="onReachBottom"
    bind:onPullDownRefreshEnd="onPullDownRefreshEnd"
  >
    <view slot="content" style="padding: 25rpx;">
      <view wx:for=" list " wx:key="name" class="item">
        <view> item.name </view>
      </view>
    </view>
  </custom-pull-down>
</view>
// pages/service/service.js
Page(
  data: 
    list: [
       name: 1 ,
       name: 2 ,
       name: 3 ,
       name: 4 ,
       name: 5 ,
       name: 6 ,
       name: 7 ,
       name: 8 ,
    ]
  ,
  onPullDownRefreshEnd()
    console.log("下拉刷新...")
  ,
  onReachBottom()
    console.log("上拉加载...")
  
)
// pages/service/service.json

  "usingComponents": 
    "custom-pull-down": "/components/customPullDown/index"
  

/* pages/service/service.wxss */
.item 
  height: 80rpx;
  text-align: center;
  background-color: aquamarine;
  margin-bottom: 30rpx;![请添加图片描述](https://img-blog.csdnimg.cn/0672f383e2674c7e890fe66746b841b7.gif)


实现效果:

这里需要注意一般上拉加载会加载下一页,要考虑事件会重复触发,需要在请求里判断当前是否是请求中状态;还需要注意如果后端没有下一页了需要显示【没有更多数据了】的字眼。

以上是关于微信小程序下拉刷新上拉加载的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序下拉刷新上拉加载

微信小程序下拉刷新上拉加载

微信小程序实现小程序下拉刷新与上拉加载

微信小程序上拉加载下拉刷新

微信小程序 - 上拉加载下拉刷新

微信小程序实现小程序下拉刷新与上拉加载