uniapp实习 下拉刷新,上滑加载功能

最近使用uniapp写小程序时很多时候需要使用加载刷新,下面是一个dome。希望可以给你提供帮助。

<template>
  <!-- 页面容器 -->
  <view class="homepage">
    <view class="content" @touchstart="touchEvent($event,'start')" @touchmove="touchEvent($event,'move')"
          @touchend="touchEvent($event,'end')" :style="{height:`calc(100vh - ${propsHeight}rpx)`}">
      <scroll-view :scroll-y="pulldown.scrollStatus" :lower-threshold="bottomDistance" class="content-scroll"
                   @scrolltoupper="scrollEvent($event,'scrolltoupper')"
                   @scrolltolower="scrollEvent($event, 'scrolltolower')" @scroll="scrollEvent($event,'scroll')">
        <!-- 下拉刷新块 -->
        <view class="pull" :style="'height:' + Math.ceil(pulldown.distance*0.18) + 'px'">
          <view style="display: flex;align-items: center">
            <view v-show="pulldown.msg!=='刷新成功'" class="loading"></view>
            <text class="pull-msg">{{ pulldown.msg }}</text>
          </view>
        </view>
        <!-- 内容插槽 -->
        <slot name="diyContent"></slot>
        <uni-load-more v-if="loadMore" :status="loadMoreStatus"/>
      </scroll-view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    /* ***************** 页面容器 - 配置 ***************** */
    /* 页面容器 - 背景色 */
    contentBackground: {type: String, default: '#f8f8f8'},
    /* 下拉刷新 是否开启 */
    showRefresh: {type: Boolean, default: false},
    /*下拉刷新 刷新完成时间 */
    refreshTime: {type: Number, default: 0},
    /* 上滑加载是否开启 */
    showUpLower: {type: Boolean, default: false},
    /*刷新组件高度*/
    propsHeight: {type: Number, default: 0},
    /* 提示  <uni-load-more status="more"></uni-load-more> */
    loadMoreStatus: {type: String, default: 'more'},
    /* 距底部/右边多远时(单位px),触发 scrolltolower 事件*/
    bottomDistance: {type: Number, default: 0},
    /* 刷新状态,是否成功 */
    loadState: {type: String, default: false},
  },
  data() {
    return {
      pulldown: {
        // 是否开启滚动
        scrollStatus: true,
        // 是否置顶
        flag: 1,
        // 初始手指高度
        startY: 0,
        // 手指滑动距离
        distance: 0,
        // 下拉刷新文本
        msg: '下拉刷新',
      },
      loadMore: false
    };
  },
  computed: {
    /* 系统属性 */
    systemInfo() {
      const systemInfo = uni.getSystemInfoSync();
      return systemInfo;
    }
  },
  watch: {
    /* 下拉刷新结束 */
    refreshTime(val, old) {
      if (val != 0) {
        this.touchEvent({}, 'redo')
      }
    },
  },
  methods: {
    /* 手指事件 */
    touchEvent(e, ty) {
      if (!this.showRefresh) {
        return;
      }
      switch (ty) {
        case 'start':
          this.pulldown.startY = e.changedTouches[0].pageY
          break;
        case 'move':
          if (e.changedTouches[0].pageY > this.pulldown.startY && this.pulldown.flag == 1) {
            this.pulldown.scrollStatus = false
            if (e.changedTouches[0].pageY - this.pulldown.startY <= 300) {
              this.pulldown.distance = (e.changedTouches[0].pageY - this.pulldown.startY)
              if (e.changedTouches[0].pageY - this.pulldown.startY >= 200) {
                this.pulldown.msg = '松开刷新'
              } else {
                this.pulldown.msg = '下拉刷新'
              }
            }
          }
          break;
        case 'end':
          if (this.pulldown.flag === 0 || this.pulldown.msg === '下拉刷新') {
            this.touchEvent('none', 'redo');
            return;
          } else if (this.pulldown.msg == '松开刷新') {
            this.pulldown.distance = 200
            this.pulldown.msg = '正在刷新...'
            this.$emit('pullRefreshData')
            this.pulldown.msg = this.loadState ? '刷新成功' : '正在刷新...'
            setTimeout(() => {
              this.pulldown.distance = this.loadState ? 0 : 200
            }, 1000)
          }
          break;
        case 'redo':
          this.pulldown.scrollStatus = true
          var interval = setInterval(() => {
            if (this.pulldown.distance > 0) {
              if (this.pulldown.distance - 10 < 0) {
                this.pulldown.distance = 0
              } else {
                this.pulldown.distance -= 10
              }
            } else {
              clearInterval(interval);
            }
          }, 5)
          break;
      }
    },
    /* 滚动事件 */
    scrollEvent(e, ty) {
      this.loadMore = true
      switch (ty) {
        case 'scrolltoupper':
          this.pulldown.flag = 1
          // 透明渐变状态+导航
          if (this.showOpacityBar) {
            this.opacityValue = 0
          }
          break;
        case 'scrolltolower':
          this.$emit('loadingMore');
          break;
        case 'scroll':
          if (e.detail.scrollTop > 0) {
            this.pulldown.flag = 0
          }
          break;
        default:
          break;
      }
    },
  },
}
</script>

<style>
scroll-view ::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
  background-color: transparent;
}
</style>
<style lang="scss" scoped>
@import '../login/font-family';

.homepage {
  position: relative;

  .content {
    width: 100%;
    .content-scroll {
      width: 100%;
      height: 100%;

      .pull {
        width: 100%;
        height: 100rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;

        .pull-msg {
          font-size: 14px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          overflow: hidden;
          color: #666666;
        }
      }

      .up {
        width: 100%;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;

        .up-msg {
          font-size: 14px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          overflow: hidden;
          color: #666666;
        }
      }

      .safearea {
        width: 100%;
      }
    }
  }
}

.loading {
  margin-right: 5rpx;
  width: 20rpx;
  height: 20rpx;
  border-radius: 50%;
  border: 2rpx solid transparent;
  border-top: 2rpx solid #000;
  border-left: 2rpx solid #000;
  animation: rotate 1s infinite linear;
}

@keyframes rotate {
  100% {
    transform: rotate(360deg);
  }
}
</style>

直接新建组件引入即可使用。

<view-content @pullRefreshData="flushedData" @loadingMore="loadingMoreData" ref="scrollView"
                    :loadMoreStatus="userStatus" :bottom-distance="3" :load-state="loading"
                    :showRefresh="true" :propsHeight="770" :showUpLower="true">
        <view slot="diyContent" class="listBox">
          
        </view>
      </view-content>

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

裴斗娜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值