mand-mobile框架:无法执行 ScrollView 下拉刷新/上拉加载

mand-mobile 是滴滴团队的前端UI组件库, 本人自己基本是不使用的。这次主要想写的东西是关于mand-mobile中的scrollView,即上拉加载以及下拉刷新两个。是因为同事在用这套框架写这个需求时总是出现两个问题无法解决:

  1. 无法取消在下拉刷新后就会执行上拉加载问题
  2. 当下拉刷新执行后,无法触发二次调用上拉加载

本文主要是围绕这两个问题编辑(文章结尾附带完整代码)。

mand-mobile 的使用


首先,我们先使用这套UI来还原问题出现的原因。


第一步:安装UI组件库;

npm install mand-mobile --save
# OR 
yarn add mand-mobile

接下来就是在main.js文件中引入mand-mobile

// 引入UI
import mandMobile from 'mand-mobile'
import 'mand-mobile/lib/mand-mobile.css'
import { ScrollView } from 'mand-mobile' // 这是滚动区域
// 使用UI
Vue.use(mandMobile)
Vue.component(ScrollView.name, ScrollView)

这里就是在组件中使用ScrollView,实现上拉加载以及下拉刷新需求问题:

<!-- 滚动区域 -->
 <md-scroll-view ref="scrollView"
                  :scrolling-x="false"
                  :is-prevent="true"
                  @scroll="$scroll"
                  @refreshing="$onRefresh"
                  @end-reached="$onEndReached">
    <!-- 下拉刷新 -->
    <md-scroll-view-refresh slot="refresh"
                            slot-scope="{ scrollTop, isRefreshActive, isRefreshing }"
                            :scroll-top="scrollTop"
                            :is-refreshing="isRefreshing"
                            :is-refresh-active="isRefreshActive"></md-scroll-view-refresh>
  	<!-- 页面主体-数据主页 -->
    <ul class="mine">
      <li class="items"
          v-for="(item,index) in list"
          :key="index">{{index+1}}</li>
      <!-- 上拉加载的提示信息 -->
      <li>
        <md-scroll-view-more slot="more"
                             :is-finished="isFinished">
        </md-scroll-view-more>
      </li>
    </ul>
  </md-scroll-view>
 // 引入
 import { ScrollViewRefresh, ScrollView, ScrollViewMore } from 'mand-mobile'

 // 使用
 components: {
    [ScrollViewRefresh.name]: ScrollViewRefresh,
    [ScrollView.name]: ScrollView,
    [ScrollViewMore.name]: ScrollViewMore
  },

样式效果图如下:
在这里插入图片描述

结构写好了

功能需求

methods中添加代码,实现上拉刷新和下拉加载功能:

   $onRefresh() {
      setTimeout(() => {
        console.log('刷新恢复最初页面信息')
        this.list = 15 // 恢复初始数据
        this.$refs.scrollView.finishRefresh()
        this.isFinished = false // 可以重新加载
        this.$refs.scrollView.finishLoadMore()
      }, 2000)
    },
   $onEndReached() {
      console.log('5555555555', this.nums)
      if (this.isFinished) {
        console.log('数据加载完了,不可再次执行3')
        return
      }
      setTimeout(() => {
        this.list += 10
        if (this.list >= 40) {
          // 数据加载完了,不可再次执行
          this.isFinished = true
        }
        console.log('阶段加载结束2')
        this.$refs.scrollView.finishLoadMore()
      }, 1000)
    }

加载前的样式:
在这里插入图片描述
加载后的效果:数据发生变动,证明上拉加载完成;
在这里插入图片描述
下拉刷新
在这里插入图片描述
刷新结束后:数据恢复初始状态,上拉加载可再次执行;

出现的问题

问题1 - 无法取消在下拉刷新后就会执行上拉加载

按照mand-mobile官网案例文档,我个人感觉如果上拉加载$onEndReached和下拉刷新在同一个组件中使用,那么下拉刷新执行后就会默认触发上拉加载$onEndReached。但是有时候我们在下拉刷新的方法体中重置了初始化或者其他什么原因,导致我们不需要在刷新后还去触发加载更多。

官方是没有这个解决方法的,或者是我自己太菜了,没有找到。

我的解决办法是:使用一个变量来判断当前是刷新还是加载,如果是刷新,那么就通知$onEndReached不要执行;反之,就让$onEndReached执行加载。

那么,用什么变量来做判断条件呢?

后面看了官方文档,发现有个@scroll属性,它可以获取到当前页面滚动距离顶部的距离,并且有个最恒定的情况:刷新时,top值小于等于零;加载时,top大于等于零。

具体的实际代码:

在局域外定义判断数组

let scrollTopArr= []

methods滚动方法中写好处理逻辑:

  $scroll({ scrollTop }) {
      scrollTopArr.push(scrollTop) // 获取滚动数据
      for (let i = 0; i < scrollTopArr.length; i++) {
        if (scrollTopArr[i] == 0) scrollTopArr.splice(i, 1) // 删除刷新与加载都有的数 0 
        if (scrollTopArr[i] > 0) this.nums = true // 可以重新加载
        if (scrollTopArr[i] < 0) this.nums = false // 不可以重新加载
      }
      scrollTopArr= []
    },

在上拉加载中进行函数判断:

  $onEndReached() {
      console.log('5555555555', this.nums)
      if (this.isFinished) {
        console.log('数据加载完了,不可再次执行3')
        return
      }
      // 如果是刷新时触发的,就不可以执行加载
      if (this.nums) {
        console.log('正在进行')
        setTimeout(() => {
          this.list += 10
          if (this.list >= 40) {
            // 数据加载完了,不可再次执行
            this.isFinished = true
          }
          console.log('阶段加载结束2')
          this.$refs.scrollView.finishLoadMore()
        }, 1000)
      } else {
        console.log('未执行')
      }
    }

问题2 - 当下拉刷新执行后,无法触发二次调用上拉加载

将下面这两句代码:

this.isFinished = false; // 可以重新加载
this.$refs.scrollView.finishLoadMore();

放在刷新 方法/接口 中的then里,如下:

// 假设
$onRefresh() {
  	getApi().then( () => {
  	  this.isFinished = false // 可以重新加载
  	  this.$refs.scrollView.finishLoadMore() // 通知加载结束
  	})
  }

问题3 - ScrollView初始化成功后,不会自动触发上拉加载

md-scroll-view加上:immediate-check-end-reaching

附件 - 代码

template 部分:

<template>
  <md-scroll-view ref="scrollView"
                  :scrolling-x="false"
                  :is-prevent="true"
                  @scroll="$scroll"
                  @refreshing="$onRefresh"
                  @end-reached="$onEndReached">
    <md-scroll-view-refresh slot="refresh"
                            slot-scope="{ scrollTop, isRefreshActive, isRefreshing }"
                            :scroll-top="scrollTop"
                            :is-refreshing="isRefreshing"
                            :is-refresh-active="isRefreshActive"></md-scroll-view-refresh>
    <ul class="mine">
      <li class="items"
          v-for="(item,index) in list"
          :key="index">{{index+1}}</li>
      <li>
        <md-scroll-view-more slot="more"
                             :is-finished="isFinished">
        </md-scroll-view-more>
      </li>
    </ul>
  </md-scroll-view>
</template>

JavaScript :

<script>
import { ScrollViewRefresh, ScrollView, ScrollViewMore } from 'mand-mobile'
let scrollTopArr = []

export default {
  components: {
    [ScrollViewRefresh.name]: ScrollViewRefresh,
    [ScrollView.name]: ScrollView,
    [ScrollViewMore.name]: ScrollViewMore
  },
  data() {
    return {
      list: 15,
      isFinished: false,
      nums: true
    }
  },
  mounted() {
    window.ScrollViewTrigger1 = () => {
      this.$refs.scrollView.triggerRefresh()
    }
  },
  methods: {
    $scroll({ scrollTop }) {
      scrollTopArr.push(scrollTop)
      for (let i = 0; i < scrollTopArr.length; i++) {
        if (scrollTopArr[i] == 0) scrollTopArr.splice(i, 1)
        if (scrollTopArr[i] > 0) this.nums = true // 可以重新加载
        if (scrollTopArr[i] < 0) this.nums = false // 不可以重新加载
      }
      scrollTopArr = []
    },
    $onRefresh() {
      setTimeout(() => {
        console.log('刷新恢复最初页面信息')
        this.list = 15 // 恢复初始数据
        this.$refs.scrollView.finishRefresh()
        this.isFinished = false // 可以重新加载
        this.$refs.scrollView.finishLoadMore()
      }, 2000)
    },
    $onEndReached() {
      console.log('5555555555', this.nums)
      if (this.isFinished) {
        console.log('数据加载完了,不可再次执行3')
        return
      }
      if (this.nums) {
        console.log('正在进行')
        setTimeout(() => {
          this.list += 10
          if (this.list >= 40) {
            // 数据加载完了,不可再次执行
            this.isFinished = true
          }
          console.log('阶段加载结束2')
          this.$refs.scrollView.finishLoadMore()
        }, 1000)
      } else {
        console.log('未执行')
      }
    }
  }
}
</script>

css部分:

<style>
.mine {
  width: 100%;
  height: 527px;
  padding-bottom: 40px;
  overflow: hidden;
  overflow-y: auto;
  background: #ff11f2;
}
.items {
  width: 80%;
  height: 40px;
  margin: auto;
  margin-top: 2px;
  background: #999999;
}
</style>
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一年两个

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

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

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

打赏作者

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

抵扣说明:

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

余额充值