微信小程序中下拉刷新和上拉加载功能怎么实现?「附代码」

1. 下拉刷新实现

在微信小程序中,下拉刷新是一种常见的页面交互方式,用户可以通过向下拉拖动页面实现刷新,使页面内容更新。下面介绍下拉刷新的具体实现。

1.1 在wxml文件中添加下拉刷新组件

<!-- 在需要下拉刷新的页面添加该组件 -->

<scroll-view

class="scrollview"

scroll-y="true"

bindscrolltoupper="upper"

style="height: {{pageHeight}}px;">

//页面内容

</scroll-view>

// 添加下拉刷新组件

<view class="refresh-view"

hidden="{{!isRefreshing}}"

catchtouchmove="touchmove">

<image src='/images/refresh.png'

class="refresh-icon {{isRefreshAnimation? 'refresh-icon-ani':''}}"

style="{{getTransformStyle()}}">

</image>

</view>

上述代码添加了一个scroll-view,这是一个可滚动的区域,我们可以在其中添加页面内容。同时,在scroll-view中通过bindscrolltoupper绑定了一个名为upper的事件,这是我们用来触发下拉刷新的事件。最后,在scroll-view外部添加了一个view,这是实现下拉刷新动画的自定义组件。在该view中,我们添加了一个image和动画实现下拉刷新效果。isRefreshing和isRefreshAnimation是在js中定义的状态量,用来开启和关闭下拉刷新、加载动画。

1.2 在js文件中实现下拉刷新功能

const db = wx.cloud.database()

const app = getApp()

Page({

/**

* 页面的初始数据

*/

data: {

pageHeight: 0, // 页面高度

isRefreshing: false, // 是否正在刷新

isRefreshAnimation: false, // 下拉刷新动画是否正在执行

transform: -60, // 匹配下拉刷新图片高度

pageNum: 1, // 请求页计数器

pageSize: 10, // 每页请求数据量

dataList: [], // 数据列表

isEnd: false, // 是否请求到最为数据,触底加载使用

},

onLoad: function (options) {

const system = wx.getSystemInfoSync()

this.setData({

pageHeight: system.screenHeight - (50 * system.screenWidth / 750)

})

this.loadDataList()

},

touchmove(e) {

e.stopPropagation()

e.preventDefault()

},

// 下拉时触发

upper(e) {

if (!this.data.isRefreshAnimation && !this.data.isEnd) {

this.setData({

isRefreshing: true,

isRefreshAnimation: true,

})

}

},

// 数据请求

loadDataList(isLoadMore = false) {

const { pageNum, pageSize } = this.data

wx.showLoading({

title: '数据加载中',

})

db.collection('dataList')

.skip((pageNum - 1) * pageSize)

.limit(pageSize)

.get()

.then((res) => {

...

wx.hideLoading()

})

.catch((error) => {

wx.hideLoading()

})

},

// 下拉刷新动画结束后触发,开始数据请求

onPullDownRefresh() {

if (!this.data.isRefreshAnimation && !this.data.isEnd) {

this.setData({

isRefreshing: true,

isRefreshAnimation: true,

})

this.loadDataList()

}

},

// 上拉加载

onReachBottom() {

const { isEnd } = this.data

if (!isEnd) {

this.setData({

pageNum: this.data.pageNum + 1,

})

this.loadDataList(true)

}

},

})

上述代码中的upper是下拉时触发的事件,在该事件中,我们会更新isRefreshing和isRefreshAnimation的状态,开启刷新动画效果。在onPullDownRefresh事件中,也会触发下拉刷新,同样也会开启下拉刷新动画效果。onPullDownRefresh事件在刷新动画结束后自动触发,因此我们可以在该事件中添加数据请求的代码。在下拉刷新动画结束后,还可以通过控制isRefreshing和isRefreshAnimation的状态来关闭刷新动画效果,达到下拉刷新释放重置的效果。

2. 上拉加载实现

上拉加载是微信小程序中相对比较常见的一种页面交互方式,用户可以向上滑动页面加载更多内容。下面介绍上拉加载的具体实现方法。

2.1 获取滚动区域高度

const system = wx.getSystemInfoSync()

this.setData({

pageHeight: system.screenHeight - (50 * system.screenWidth / 750)

})

上述代码获取了页面滚动区域的高度,其中50 * system.screenWidth / 750是为了适配不同设备的高度。这个高度值可以通过相应的计算方式得到。获取到滚动区域的高度后,我们就可以在wxml中添加scroll-view,这是一个可滚动的区域。

2.2 触底加载数据

// 上拉加载

onReachBottom() {

const { isEnd } = this.data

if (!isEnd) {

this.setData({

pageNum: this.data.pageNum + 1,

})

this.loadDataList(true)

}

},

上述代码中,我们通过onReachBottom事件来实现上拉加载功能。在该事件中,我们会更新计数器pageNum的值,请求新的数据,数据请求成功后更新dataList的值,达到数据更新的目的。同时,我们还需要一个isEnd状态量来判断数据是否已经请求完毕,如果已经请求完毕,就没有必要再次请求数据。isEnd的值可以通过计算当前数据量和总数据量得到,判断数据是否已经全部请求。

3. 完整代码

下面是完整的实现下拉刷新和上拉加载的代码。

const db = wx.cloud.database()

Page({

/**

* 页面的初始数据

*/

data: {

pageHeight: 0, // 页面高度

isRefreshing: false, // 是否正在刷新

isRefreshAnimation: false, // 下拉刷新动画是否正在执行

transform: -60, // 匹配下拉刷新图片高度

pageNum: 1, // 请求页计数器

pageSize: 10, // 每页请求数据量

dataList: [], // 数据列表

isEnd: false, // 是否请求到最为数据,触底加载使用

},

/**

* 生命周期函数--监听页面加载

*/

onLoad: function (options) {

const system = wx.getSystemInfoSync()

this.setData({

pageHeight: system.screenHeight - (50 * system.screenWidth / 750)

})

this.loadDataList()

},

touchmove(e) {

e.stopPropagation()

e.preventDefault()

},

// 下拉时触发

upper(e) {

if (!this.data.isRefreshAnimation && !this.data.isEnd) {

this.setData({

isRefreshing: true,

isRefreshAnimation: true,

})

}

},

// 数据请求

loadDataList(isLoadMore = false) {

const { pageNum, pageSize } = this.data

wx.showLoading({

title: '数据加载中',

})

db.collection('dataList')

.skip((pageNum - 1) * pageSize)

.limit(pageSize)

.get()

.then((res) => {

const { data } = res

let { dataList } = this.data

if (isLoadMore) {

dataList = dataList.concat(data)

} else {

dataList = data

}

const isEnd = dataList.length > 0 && dataList.length % pageSize != 0

this.setData({

dataList,

isEnd,

isRefreshing: false,

isRefreshAnimation: false,

})

wx.hideLoading()

wx.stopPullDownRefresh()

})

.catch((error) => {

wx.hideLoading()

wx.stopPullDownRefresh()

})

},

// 下拉刷新动画结束后触发,开始数据请求

onPullDownRefresh() {

if (!this.data.isRefreshAnimation && !this.data.isEnd) {

this.setData({

isRefreshing: true,

isRefreshAnimation: true,

})

this.loadDataList()

}

},

// 上拉加载

onReachBottom() {

const { isEnd } = this.data

if (!isEnd) {

this.setData({

pageNum: this.data.pageNum + 1,

})

this.loadDataList(true)

}

},

})