PHP前端开发

小程序的下拉刷新问题

百变鹏仔 1个月前 (03-12) #前端问答
文章标签 程序

在小程序中onload生命钩子只在页面创建时调用一次,在做navigateto页面跳转后,返回上级页面,由于navigateto跳转只是隐藏了当前页面,因此返回上一级页面时onload生命钩子不会再次执行,这样带来的好处是页面能快速展示出来,但是onload中的请求数据不会实时更新,这时候就需要一个下拉刷新的操作来帮助用手动更新页面数据,接下来这篇文章将会介绍小程序中实现下拉刷新的三种方式

enablePullDownRefresh

enablePullDownRefresh是最容易实现下拉刷新的方法,在json文件中将enablePullDownRefresh设置为true,在Page中监听onPullDownRefresh事件即可,支持点击顶部标题栏回到顶部,自定义标题栏时会失效,还可以通过直接调用wx.startPullDownRefresh()触发下拉刷新事件,产生下拉刷新动画,处理完下拉刷新中的数据更新后调用wx.stopPullDownRefresh()结束动画即可。

这种形式的下拉刷新的优点很明显就是简单,没有限制,但是缺点也同样明显:

scroll-view

scroll-view是官方的一个滚动视图组件,使用很简单,想要设置上拉刷新代码如下:

<scroll-view class="scroll" scroll-y bindscrolltoupper="refresh">  <view class="content">content</view></scroll-view>

想要利用scroll-view实现上拉刷新,需要注意:

scroll-view缺点:

scroll-view优点:

官方并不推荐使用scroll-view做下拉刷新,官方文档上有这样一个tip

自定义下拉刷新

自定义下拉刷新最主要希望解决的问题还是在Android使用enablePullDownRefresh时fixed定位的标题栏或导航栏会被下拉的问题,同时两端在下拉刷新时的动画保持一致,其实实现起来并不难,接下来就看看具体实现:
wxml:

<view class="scroll" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd">  <view class="animation">    <view class="loading"></view>    <text class="tip">{{state === 0 ? '下拉刷新' : state === 1? '松开刷新' : '刷新中'}}</text>  </view>  <view style="transform: translateY({{translateHeight}}rpx)">    <slot name="content"></slot>  </view></view>

这个文件定义组件的模版,有一个滚动view包裹,绑定了touch事件,里面包含下拉刷新时的动画,和一个slot,slot用于插入滚动列表的内容
wxss:

.animation {  display: flex;  justify-content: center;  align-items: center;  width: 100%;  height: 150rpx;  margin-bottom: -150rpx;  background-color: #fff;}.loading {  width: 30rpx;  height: 30rpx;  border:6rpx solid #333333;  border-bottom: #cccccc 6rpx solid;  border-radius: 50%;  animation:load 1.1s infinite linear;      }@keyframes load{   from{    transform: rotate(0deg);  }  to{    transform: rotate(360deg);  }}.tip {  margin-left: 10rpx;  color: #666;}

样式文件这没什么特别的
js:

let lastY = 0 // 上一次滚动的位置let scale = 750 / wx.getSystemInfoSync().windowWidth // rpx转化比例Component({  options: {    multipleSlots: true  },  data: {    scrollTop: 0,    translateHeight: 0, // 平移距离    state: -1  },  properties: {    // 触发下拉刷新的距离    upperDistance: {      type: Number,      value: 150    }  },  methods: {    // 监听滚动,获取scrollTop    onPageScroll (e) {      this.data.scrollTop = e.scrollTop    },    touchStart (e) {      lastY = e.touches[0].clientY    },    touchMove (e) {      let clientY = e.touches[0].clientY      let offset = clientY - lastY      if (this.data.scrollTop > 0 || offset < 0) return      this.data.translateHeight += offset      this.data.state = 0      lastY = e.touches[0].clientY      if (this.data.translateHeight - this.data.scrollTop * scale > this.data.upperDistance) {        this.data.state = 1      }      this.setData({        translateHeight: this.data.translateHeight,        state: this.data.state      })    },    touchEnd (e) {      if (this.data.translateHeight - this.data.scrollTop * scale > this.data.upperDistance) {        this.setData({          translateHeight: 150        })        this.triggerEvent('scrolltoupper')        this.setData({          state: 2        })      } else if (this.data.scrollTop <= 0) {        this.stopRefresh()      }    },    //  停止刷新    stopRefresh () {      this.setData({        translateHeight: 0,        state: -1      }, () => {        wx.pageScrollTo({          scrollTop: 0,          duration: 0        })      })    }  }})

这个下拉刷新组件最重要的是控制下拉刷新的时机,代码体现就是定义了一个upperDistance,下拉刷新的距离来判断是否执行刷新。手指滑动时,获取滑动距离,translateHeight累加用于展示,在touchEnd事件中判断滑动距离是否达到设定值,达到设定值就发送scrolltoupper事件,在父组件中监听即可,否则停止刷新。

使用:

<header title="下拉刷新" background="#fff"></header><refresh-scroll id="refreshScroll" bindscrolltoupper="refresh">  <view class="item" slot="content" wx:for="{{list}}">{{item}}</view></refresh-scroll>
Page({  data: {    list: []  },  onLoad: function () {    this.refreshScroll = this.selectComponent('#refreshScroll')    for (let i = 0; i < 10; i++) {      this.data.list.push(i)    }    this.setData({      list: this.data.list    })  },  onPageScroll (e) {    this.refreshScroll.onPageScroll(e)  },  onReachBottom () {    wx.showLoading({      title: 'onReachBottom'    })    setTimeout(() => {      wx.hideLoading()    }, 1000)  },  refresh: function (e) {    setTimeout(() => {      this.refreshScroll.stopRefresh()    }, 1000)  }})

在使用时关键是要将页面中onPageScroll中获取的值传递下去,然后bindscrolltoupper监听scrolltoupper事件,执行刷新操作然后再调用stopRefresh停止刷新,下来看真机上的测试效果:

iOS:

Android:

在真机测试时,表现都还不错,当然了,这只是自定义下拉刷新的一个简单组件例子,如果需要用于到实际项目,可能还需要自己去完善,毕竟不同的人应用的场景不同,这里只是给出了一个思路而已

总结

本篇文章介绍了小程序下拉刷新时的三种方法,前两种都是小程序官方提供的,最后一种是个人的思考总结,写的也比较简单,想要项目应用,还需要自己完善,只希望为大家做自定义下拉刷新提供一个思路。

推荐教程:《微信小程序》