uniapp下拉刷新
uniapp的下拉刷新有兩個方法, 一種是整體的下拉刷新, 使用頁面生命周期函數onPullDownRefresh; 另外一種是局部的下拉刷新也叫自定義下拉刷新, 使用scrpll-view組件中的自定義下拉刷新事件。
一.整個頁面的刷新(onPullDownRefresh)
在 js 中定義 onPullDownRefresh 處理函數(和onLoad等生命周期函數同級),監聽該頁面用戶下拉刷新事件。
【官方文檔】這里不再做過多介紹!今天的重點在下面👇
二.自定義頁面刷新(scroll-view)
組件中遇到的問題
- 觸發不了下拉(原因排查)
- scroll-view組件外部沒有用view包裹. 官網雖然沒有說這個問題, 但是如果外部沒有一個view單獨包裹着這個組件, 就沒有辦法觸發scroll-view組件中的事件。
- scroll-view沒有設置固定高, 在css中設置height, 設置多高就在多高的區域展現. 比如設置高為50vh(100vh為滿屏), 則組件里邊的內容只會在半屏內上下滾動,不會觸發page的滾動條只會觸發scroll-view的滾動條. 如果高度不好給確定值, 可以使用
scss(lang='scss')
中的calc計算, 例子中有體現.(注意使用calc計算時, -左右一定要有空格)。 - 設置高為百分比的話也不能觸發下拉. 高可以使用max-hight, 不能使用min-hight。
- 沒有設置scroll-y
- 沒有滾動到頂部觸發下拉, 而是在可視頁面中觸發下拉
- 官方默認無論page的滾動條在哪個位置, 只要在scroll-view頁面上下拉都會觸發下拉函數, 這樣用戶體驗非常差. 可以使用
@scroll
滾動時觸發的函數來獲取scroll-view滾動條的位置, 進而來控制refresher-enabled
開啟和關閉自定義下拉刷新. 當scroll-view的滾動條滾動到頂部時, 使refresher-enabled
為true, 其他條件為false。
直接上代碼看👀:
html:
<template>
<view>
<scroll-view
show-scrollbar="true"
style="height: 300px"
scroll-y="true"
:refresher-enabled="isOpenRefresh"
:refresher-triggered="triggered"
:refresher-threshold="100"
refresher-background="gray"
@refresherpulling="onPulling"
@refresherrefresh="onRefresh"
@refresherrestore="onRestore"
@refresherabort="onAbort"
@scroll="onScroll"
>
<view v-if="!isOpenRefresh">別拉了,沒有更多了~</view>
<view class="item" v-for="(item, index) in dataList" :key="index">{{ item }}</view>
</scroll-view>
</view>
</template>
基本上下拉刷新用到的屬性方法也就這幾個了!
js:
export default {
data() {
return {
triggered: false,
dataList: [],
arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
page: 0,
isOpenRefresh: true // 是否開啟下拉
};
},
onLoad() {
this._freshing = false;
this.getData()
},
methods: {
dealArray(array, groupNum) {
let temp = [];
for (let i = 0, len = array.length; i < len; i += groupNum) {
temp.push(array.slice(i, i + groupNum));
}
return temp;
},
// 自定義下拉刷新控件被下拉
onPulling(e) {
console.log("onpulling", e);
if (e.detail.deltaY < 0) return // 防止上滑頁面也觸發下拉
this.triggered = true;
},
// 自定義下拉刷新被觸發
onRefresh() {
if (this._freshing) return;
this._freshing = true;
this.page++;
setTimeout(() => {
this.triggered = false;
this._freshing = false;
this.getData();
}, 500);
},
// 自定義下拉刷新被復位
onRestore() {
this.triggered = 'restore'; // 需要重置
console.error("onRestore");
},
// 自定義下拉刷新被中止
onAbort() {
console.error("onAbort");
},
getData() {
// 前端模擬分頁
let temp = this.dealArray(this.arr, 3)
if (this.page > temp.length - 1) {
this.isOpenRefresh = false
return
}
this.dataList.push(...temp[this.page])
}
},
};
style:
<style>
view {
text-align: center;
}
.item:nth-child(odd) {
background-color: antiquewhite;
}
.item:nth-child(even) {
background-color: aquamarine;
}
</style>
【注意】scroll-view 下拉刷新會出現上滑頁面也觸發下拉,可以在
@refresherpulling="onPulling"
這個方法,如下if (e.detail.deltaY < 0) return
// 防止上滑頁面也觸發下拉
演示:
出現,在頁面上任意位置只要下滑動頁面就會觸發下拉,這類問題。可以使用
@scroll="onScroll"
監聽scroll-top
的值,讓其===0
時觸發,也就是到達頂部!再觸發!但是遇到其必須滑動一下頁面出現滾動條,他才會監聽!我們可以init
的時候初始化一下,令其變量初始為0!
export default class Index extends mixins(uiMixin) {
scrollTop: number = 0
// 監聽頁面是否滾動
onScroll(e) {
this.scrollTop = e.detail.scrollTop
}
// 自定義下拉刷新被觸發
onRefresh() {
if (this.scrollTop === 0) {
if (this._freshing) return;
this._freshing = true;
this.page++;
setTimeout(() => {
this.triggered = false;
this._freshing = false;
this.getData();
}, 500);
}
}
})