微信小程序原生开发功能合集二:下拉选择组件封装

Posted 军军君01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序原生开发功能合集二:下拉选择组件封装相关的知识,希望对你有一定的参考价值。

  本章实现小程序中下拉选择组件的封装实现,通过自定义组件的方式实现下拉选择功能,使用小程序的picker组件实现下拉数据的展示及相关自定义处理,封装数据加载过程,数据切换逻辑监听等。
  本节实现select组件的开发说明,另使用nodejs创建express服务器,为远程加载数据提供数据接口,代码可从源码中下载。

  另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:
   1. CSDN课程: https://edu.csdn.net/course/detail/37977
   2. 51CTO课程:https://edu.51cto.com/course/100044719.html

一、背景介绍

  小程序未提供专门的select组件,使用下拉选择功能时需要自定义封装,只提供了picker组件,但是picker组件无法进行下拉内容的自定义,如展示图片信息、实现多选功能、数据量大时的分页加载、搜索功能等;且大多数情况下需要选择的数据都需要从远程加载,小程序为提供数据加载过程的封装。

  所以需要进行封装实现用于下拉选择的组件,将数据加载过程、数据切换处理过程及自定义功能进行封装,实现专门的下拉选择组件。

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

微信小程序官方没有给出具体的下拉刷新和上拉加载组件,我们可以基于小程序原生组件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)


实现效果:

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

以上是关于微信小程序原生开发功能合集二:下拉选择组件封装的主要内容,如果未能解决你的问题,请参考以下文章

原生的微信小程序有下拉刷新功能,怎么取消下拉刷新?不希望它刷新

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

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

h5微信支付功能封装

微信小程序组件封装及调用-原生

微信小程序原生组件swiper在mpvue工程中使用注意事项