使用vue實現(xiàn)滑動滾動條來加載數(shù)據(jù)
實現(xiàn)思路
- 首先,我們需要在vuejs中引入
axios - 然后,我們需要從
vue中,引入onMounted,onUnmounted生命周期鉤子函數(shù) 然后,我們需要在onMounted函數(shù)中,進行監(jiān)聽 而在onUnmounted函數(shù)中,我們需要取消監(jiān)聽,解綁 - 編寫事件處理函數(shù)
handleScroll, 獲取變量scrollTop是滾動條滾動時,距離頂部的距離,獲取變量scrollHeight是滾動條的總高度,獲取變量clientHeight是滾動條可視區(qū)域的高度 - 當(dāng)滾動條到達底部,并且距離底部小于10px時,加載數(shù)據(jù),也就是請求axios數(shù)據(jù),頁碼++,重新加載數(shù)據(jù)函數(shù)
- 為了防止用戶頻繁觸發(fā)下拉滑動滾動條,往往需要添加一個函數(shù)防抖,在指定的時間內(nèi),只執(zhí)行最后一次事件處理函數(shù),避免頻繁請求數(shù)據(jù),給服務(wù)器造成壓力
代碼實現(xiàn)
<template>
<div>
<div>
<el-button type="primary" @click="handleBtnGetJoke">請求數(shù)據(jù)</el-button>
<el-button type="danger" @click="handleBtnClearData" v-if="aDatas.length > 0?true:false">清空數(shù)據(jù)</el-button>
</div>
<div>
<ul v-if="aDatas.length > 0?true:false">
<li class="joke-list" v-for="item in aDatas"
:key="item.hashId">{{ item.content }}
</li>
<div class="loading" v-if="aDatas.length > 0?true:false">
<el-button size="mini" type="primary" @click="handleBtnLoading" >加載</el-button>
</div>
</ul>
</div>
</div>
</template>
<script setup>
import axios from "axios";
import { ref,onMounted,onUnmounted } from "vue";
let aDatas = ref([]);
let page = ref(1);
let pagesize = ref(20);
onMounted(() => {
// 獲取數(shù)據(jù)
handleBtnGetJoke();
window.addEventListener('scroll', debounce(handleScroll,500));
})
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll);
})
// 事件處理函數(shù)
function handleScroll() {
// 變量scrollTop是滾動條滾動時,距離頂部的距離
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// 變量scrollHeight是滾動條的總高度
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
// 變量clientHeight是滾動條可視區(qū)域的高度
const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
// 當(dāng)滾動條到達底部,并且距離底部小于10px時,加載數(shù)據(jù)
if (scrollTop + clientHeight - scrollHeight <= 10) {
page.value++;
handleBtnGetJoke();
}
}
// 函數(shù)的防抖
function debounce(method, duration) {
var timer = null;
return function(){
var that = this,
args = arguments;
// 在本次調(diào)用之間的一個間隔時間內(nèi)若有方法在執(zhí)行,則終止該方法的執(zhí)行
if(timer) {
clearTimeout(timer);
}
// 開始執(zhí)行本次調(diào)用
timer = setTimeout(function(){
method.apply(that,args);
}, duration)
}
}
async function handleBtnGetJoke() {
const params = {
key: 'aa1b7ad08be2a09a4e0d2d46897e2dc8',
page: page.value,
pagesize:pagesize.value,
time: 1418816972
}
const response = await axios.get('/api/joke/content/text.php',{params})
console.log(response);
if(response.status == 200) {
const { data } = response.data.result;
console.log(data);
aDatas.value = aDatas.value.concat(data);
if(page.value*pagesize.value >= data.length) {
alert("沒有更多數(shù)據(jù)了")
}
}
}
// 加載數(shù)據(jù),疊加
function handleBtnLoading() {
page.value++;
handleBtnGetJoke();
}
// 清空數(shù)據(jù)
function handleBtnClearData() {
aDatas.value = [];
}
</script>
<style scoped>
.joke-list {
list-style-type: decimal;
list-style-position: outside;
padding: 5px 0;
border-bottom: dashed 1px #ccc;
}
.loading {
margin: 0 auto;
text-align:center;
}
</style>
其中核心防抖函數(shù)如下所示,實現(xiàn)方式也很簡單,就是利用定時器,在規(guī)定的時間內(nèi),如果再次觸發(fā),則清除定時器,重新開始計時。
只執(zhí)行最后一次
// 函數(shù)的防抖
function debounce(method, duration) {
var timer = null;
return function(){
var that = this,
args = arguments;
// 在本次調(diào)用之間的一個間隔時間內(nèi)若有方法在執(zhí)行,則終止該方法的執(zhí)行
if(timer) {
clearTimeout(timer);
}
// 開始執(zhí)行本次調(diào)用
timer = setTimeout(function(){
method.apply(that,args);
}, duration)
}
}
至于怎么樣判斷數(shù)據(jù)是否加載完畢,到最后一頁
每次在請求完成數(shù)據(jù)的時候去判斷一下當(dāng)前的 page × pagesize是否已經(jīng)大于等于接口返回的total值就行了,也可以是pageNum 等于total 的時候,就說明已經(jīng)沒有數(shù)據(jù)了,可以提示用戶了
if(page.value*pagesize.value >= data.length) {
alert("沒有更多數(shù)據(jù)了")
}
總結(jié)
其實這個功能很簡單,但是寫起來還是有點麻煩,因為涉及到異步請求,所以需要判斷數(shù)據(jù)是否加載完畢,還要判斷是否最后一頁,還要判斷是否還有數(shù)據(jù),還要判斷是否需要提示用戶沒有更多數(shù)據(jù)了,所以代碼量還是挺多的,但是寫完之后,感覺還是挺有成就感的。
什么上拉,下拉刷新,下拉加載更多,其實原理都差不多,都是利用了防抖函數(shù),然后利用定時器,在規(guī)定的時間內(nèi),如果再次觸發(fā),則清除定時器,重新開始計時。 實現(xiàn)方式都差不多
以上就是vuejs實現(xiàn)滑動滾動條來加載數(shù)據(jù)的詳細內(nèi)容,更多關(guān)于vuejs滾動條加載數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue + element-ui實現(xiàn)簡潔的導(dǎo)入導(dǎo)出功能
Element-UI是餓了么前端團隊推出的一款基于Vue.js 2.0 的桌面端UI框架,手機端有對應(yīng)框架是 Mint UI,下面這篇文章主要給大家介紹了關(guān)于利用vue + element-ui如何實現(xiàn)簡潔的導(dǎo)入導(dǎo)出功能的相關(guān)資料,需要的朋友可以參考下。2017-12-12
el-select 數(shù)據(jù)回顯,只顯示value不顯示lable問題
這篇文章主要介紹了el-select 數(shù)據(jù)回顯,只顯示value不顯示lable問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
Vue.js與 ASP.NET Core 服務(wù)端渲染功能整合
本文通過案例給大家詳細分析了ASP.NET Core 與 Vue.js 服務(wù)端渲染,需要的朋友可以參考下2017-11-11
vue實現(xiàn)html轉(zhuǎn)word與word全過程
本文介紹了如何在Vue中實現(xiàn)HTML轉(zhuǎn)Word功能,通過拖拽組件生成類似Word的界面,并實時預(yù)覽,主要使用了htmlDocx和htmlToDocx插件將HTML轉(zhuǎn)換為.docx格式,同時,還討論了檢查.docx文件是否損壞的方法2026-01-01
Vue2.x中的父組件傳遞數(shù)據(jù)至子組件的方法
這篇文章主要介紹了Vue2.x中的父組件數(shù)據(jù)傳遞至子組件的方法,需要的朋友可以參考下2017-05-05
VUE3中Element table表頭動態(tài)展示合計信息
本文主要介紹了在Vue中實現(xiàn)動態(tài)合計兩個字段并輸出摘要信息的方法,通過使用監(jiān)聽器和深度監(jiān)聽,確保當(dāng)數(shù)據(jù)變化時能正確更新合計結(jié)果,具有一定的參考價值,感興趣的可以了解一下2024-11-11

