Vue+Vant實(shí)現(xiàn)下拉加載功能
介紹
簡介:為了像微信一樣方便地加載更多歷史消息,我們使用vant組件來實(shí)現(xiàn)下拉加載功能。我們對組件進(jìn)行了改造,將下拉刷新變成了下拉加載更多的形式。這樣,用戶只需要在第一次下拉時手動開啟加載更多,之后只需將頁面滑動到頂部,加載更多就會自動觸發(fā),直到無數(shù)據(jù)可加載時,會顯示“無更多數(shù)據(jù)”的提示。
目標(biāo):如同微信那般,下拉加載更多歷史消息。
組件:利用vant組件的下拉刷新組件。
效果:用戶只需在第一次下拉時手動開啟加載更多,之后到達(dá)頂部時會自動觸發(fā)加載更多,直到所有數(shù)據(jù)都加載完畢,此時會出現(xiàn)提示信息:“無更多數(shù)據(jù)”。
目的:是為了讓用戶在使用過程中更加方便快捷地加載歷史消息,提高用戶體驗(yàn)。
該組件官方地址:vant-contrib.gitee.io/vant/v2/#/zh-CN/pull-refresh
效果
我寫了一個new promise,延遲了1s返回?cái)?shù)據(jù)。

開始
引入
import { PullRefresh } from "vant";
export default {
components: {
"van-pull-refresh": PullRefresh
},
}template上的使用
<div class="refresh">
<van-pull-refresh
v-model="isRefreshLoading"
pulling-text="下拉加載數(shù)據(jù)"
loosing-text="釋放即可刷新"
:success-text="isRefreshDisabled ? '無更多數(shù)據(jù)' : ''"
:success-duration="800"
:disabled="isRefreshDisabled"
@refresh="onRefresh"
>
<div ref="courseListHeight">
<div v-for="(item, index) in videoList" :key="index" class="content">
{{ item.video_id }}
</div>
</div>
</van-pull-refresh>
</div>使用的參數(shù)
我就怕大家懶得打開
Props
| 參數(shù) | 說明 | 類型 | 默認(rèn)值 |
|---|---|---|---|
| v-model | 是否處于加載中狀態(tài) | boolean | - |
| pulling-text | 下拉過程提示文案 | string | 下拉即可刷新... |
| loosing-text | 釋放過程提示文案 | string | 釋放即可刷新... |
| success-text | 刷新成功提示文案 | string | - |
| success-duration | 刷新成功提示展示時長(ms) | number / string | 500 |
| disabled | 是否禁用下拉刷新 | boolean | false |
Events
| 事件名 | 說明 | 回調(diào)參數(shù) |
|---|---|---|
| refresh | 下拉刷新時觸發(fā) | - |
數(shù)據(jù)處理
處理方案:
1、利用getBoundingClientRect監(jiān)聽滑塊到指定的區(qū)域之后,滿足判斷條件,開始請求下一頁數(shù)據(jù)。
2、阻止在規(guī)定的區(qū)域內(nèi),多次調(diào)用api.
3、利用渲染可知高度,使用scrollTo/scrollBy滾動到下拉加載的數(shù)據(jù)處。
4、請求數(shù)據(jù)結(jié)束,關(guān)閉加載中狀態(tài)以及禁用下拉刷新。
data的數(shù)據(jù)
params: {
page_size: 5,
page_num: 1,
},
isRefreshLoading: false, // 是否處于加載中狀態(tài)
isRefreshDisabled: false, // 是否禁用下拉刷新
videoList: [], // 數(shù)據(jù)內(nèi)容
courseListPageHeight: 0, // 頁面的高度
domVantRefreh: "", // 獲取van-loading到頂部的高度
lockOneApiState: false // 防止反復(fù)的請求api再初次進(jìn)頁面需要請求一次接口
beforeMount() {
this.getapi();
},下面就是對后面的數(shù)據(jù)進(jìn)行請求,在methods中
onRefresh() {
// 獲取van-loading到頂部的高度
this.domVantRefreh = document.querySelector(".van-loading");
// 加載監(jiān)聽scroll滾動事件
window.addEventListener("scroll", this.loadingPage);
this.params.page_num++;
this.getapi();
},
getapi() {
getAnchorEnjoySection({
...this.params
}).then(res => {
if (res.code == 200) {
// 第一次添加數(shù)據(jù)
if (this.params.page_num == 1) {
this.videoList = res.result.video_list;
this.$nextTick(() => {
// 渲染完成,開始滾動到最低處
window.scrollBy(0, 9999);
// 獲取第一次的頁面列表的高
this.courseListPageHeight = this.$refs.courseListHeight.clientHeight;
});
} else {
this.videoList.unshift(...(res.result.video_list));
}
// 對后面的數(shù)據(jù)進(jìn)行處理
if (res.result.video_list.length !== 0 && this.params.page_num !== 1) {
this.isRefreshDisabled = false;
this.$nextTick(() => {
// 獲取到需要滾動的高
let heightElement = this.$refs.courseListHeight.clientHeight - this.courseListPageHeight;
this.courseListPageHeight = this.$refs.courseListHeight.clientHeight;
window.scrollBy(0, heightElement);
});
}
// 請求無數(shù)據(jù)的時候
if (res.result.video_list.length == 0) {
this.isRefreshDisabled = true; //無數(shù)據(jù)了,不需要再下拉刷新了
this.isRefreshLoading = false; // 加載狀態(tài)取消
window.removeEventListener('scroll', this.loadingPage); // 取消監(jiān)聽
}
}
this.lockOneApiState = true; // 鎖狀態(tài)打開
});
},
loadingPage() {
// 由于我們給與了margin-top: 20px;有20的高度,所以使用 0 恰到好處,能再快看到加載狀態(tài)的時候,進(jìn)行了加載,同時需要:鎖的狀態(tài)是打開的,并且沒有禁用下拉刷新
if (this.domVantRefreh.getBoundingClientRect().top >= 0 && this.lockOneApiState == true && this.isRefreshDisabled == false) {
this.params.page_num++;
this.getapi();
this.lockOneApiState = false;
}
}完整代碼
我使用cnd.js引入總有點(diǎn)小問題,就直接貼出來了,以后解決來再替換。
<template>
<div class="refresh">
<van-pull-refresh
v-model="isRefreshLoading"
pulling-text="下拉加載數(shù)據(jù)"
loosing-text="釋放即可刷新"
:success-text="isRefreshDisabled ? '無更多數(shù)據(jù)' : ''"
:success-duration="800"
:disabled="isRefreshDisabled"
@refresh="onRefresh"
>
<div ref="courseListHeight">
<div v-for="(item, index) in videoList" :key="index" class="content">
{{ item }}
</div>
</div>
</van-pull-refresh>
</div>
</template>
<script>
import { PullRefresh } from "vant";
export default {
components: {
"van-pull-refresh": PullRefresh
},
data() {
return {
dataList: [111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135],
params: {
page_size: 5,
page_num: 1
},
isRefreshLoading: false, // 是否處于加載中狀態(tài)
isRefreshDisabled: false, // 是否禁用下拉刷新
videoList: [], // 數(shù)據(jù)內(nèi)容
courseListPageHeight: 0, // 頁面的高度
domVantRefreh: "", // 獲取van-loading到頂部的高度
lockOneApiState: false // 防止反復(fù)的請求api
};
},
beforeMount() {
this.getapi();
},
methods: {
onRefresh() {
// 獲取van-loading到頂部的高度
this.domVantRefreh = document.querySelector(".van-loading");
window.addEventListener("scroll", this.loadingPage);
this.params.page_num++;
this.getapi();
},
getapi() {
this.getDataList(this.params).then(res => {
console.log(res);
if (res.code == 200) {
// 第一次添加數(shù)據(jù)
if (this.params.page_num == 1) {
this.videoList = res.result.video_list;
this.$nextTick(() => {
window.scrollBy(0, 9999);
this.courseListPageHeight = this.$refs.courseListHeight.clientHeight;
});
} else {
this.videoList.unshift(...(res.result.video_list));
}
// 對后面的數(shù)據(jù)進(jìn)行處理
if (res.result.video_list.length !== 0 && this.params.page_num !== 1) {
this.isRefreshDisabled = false;
this.$nextTick(() => {
let heightElement = this.$refs.courseListHeight.clientHeight - this.courseListPageHeight;
this.courseListPageHeight = this.$refs.courseListHeight.clientHeight;
window.scrollBy(0, heightElement);
});
}
// 請求無數(shù)據(jù)的時候
if (res.result.video_list.length == 0) {
this.isRefreshDisabled = true;
this.isRefreshLoading = false;
window.removeEventListener('scroll', this.loadingPage);
}
}
this.lockOneApiState = true;
});
},
loadingPage() {
// 由于我們給與了margin-top: 20px;有20的高度,所以使用 0 恰到好處,能再快看到加載狀態(tài)的時候,進(jìn)行了加載
if (this.domVantRefreh.getBoundingClientRect().top >= 0 && this.lockOneApiState == true && this.isRefreshDisabled == false) {
this.params.page_num++;
this.getapi();
this.lockOneApiState = false;
}
},
// 偽裝數(shù)據(jù)請求
getDataList(params) {
return new Promise(
resolve => {
let result = {
code: 200,
result: {
video_list: this.dataList.splice(1 * params.page_num - 1, params.page_size)
}
};
setTimeout(() => {
resolve(result);
}, 1000);
}
);
}
}
};
</script>
<style lang="scss" scoped>
.refresh {
padding: 0 20px 20px 20px;
.content{
width: 100%;
height: 320px;
text-align: center;
margin-top: 20px;
background-color: cadetblue;
font-size: 22px;
}
}
</style>到此這篇關(guān)于Vue+Vant實(shí)現(xiàn)下拉加載功能的文章就介紹到這了,更多相關(guān)Vue Vant下拉加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?perfect-scrollbar(特定框架里使用非該框架定制庫/插件)
這篇文章主要為大家介紹了vue?perfect-scrollbar在特定框架里使用一款并非為該框架定制的庫/插件如何實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2023-05-05
解決vue前端rsa加密遇到的問題message too long for RS
這篇文章主要介紹了解決vue前端rsa加密遇到的問題message too long for RSA,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
vue中el-table格式化el-table-column內(nèi)容的三種方法
本文主要介紹了vue中el-table格式化el-table-column內(nèi)容的三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
解決iview table組件里的 固定列 表格不自適應(yīng)的問題
這篇文章主要介紹了解決iview table組件里的 固定列 表格不自適應(yīng)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11

