ScrollViewプルダウンリフレッシュ/プルアップロードを実行できません
mand-mobileは、DidiチームのフロントエンドUIコンポーネントライブラリです。基本的に、私自身は使用していません。今回書きたいのは、プルアップローディングとプルダウンリフレッシュというmand-mobile
ミドルについてscrollView
です。これは、このフレームワークを使用してこの要件を作成する場合、同僚には常に解決できない2つの問題があるためです。
无法取消在下拉刷新后就会执行上拉加载问题
;当下拉刷新执行后,无法触发二次调用上拉加载
。
この記事は主にこれら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
、現在のページスクロールの上部からの距離を取得できる属性があり、最も一定した状況があることがわかりました。更新すると、上部の値がゼロ以下になります。読み込み中、上限値はゼロ以上です。
特定の実際のコード:
ローカルエリア外の判定配列を定義する
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-プルダウンリフレッシュが実行された後、プルアップロードへの2番目の呼び出しをトリガーできません
次の2行のコードを置き換えます。
this.isFinished = false; // 可以重新加载
this.$refs.scrollView.finishLoadMore();
then
次のように、refreshメソッド/インターフェイスに配置します。
// 假设
$onRefresh() {
getApi().then( () => {
this.isFinished = false // 可以重新加载
this.$refs.scrollView.finishLoadMore() // 通知加载结束
})
}
質問3-ScrollViewが正常に初期化された後、プルアップロードは自動的にトリガーされません
でmd-scroll-view
プラス:immediate-check-end-reaching
アクセサリ-コード
テンプレート部分:
<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>