使用vue實(shí)現(xiàn)滑動(dòng)滾動(dòng)條來加載數(shù)據(jù)
實(shí)現(xiàn)思路
- 首先,我們需要在vuejs中引入
axios
- 然后,我們需要從
vue
中,引入onMounted
,onUnmounted
生命周期鉤子函數(shù) 然后,我們需要在onMounted函數(shù)中,進(jìn)行監(jiān)聽 而在onUnmounted函數(shù)中,我們需要取消監(jiān)聽,解綁 - 編寫事件處理函數(shù)
handleScroll
, 獲取變量scrollTop
是滾動(dòng)條滾動(dòng)時(shí),距離頂部的距離,獲取變量scrollHeight
是滾動(dòng)條的總高度,獲取變量clientHeight
是滾動(dòng)條可視區(qū)域的高度 - 當(dāng)滾動(dòng)條到達(dá)底部,并且距離底部小于10px時(shí),加載數(shù)據(jù),也就是請求axios數(shù)據(jù),頁碼++,重新加載數(shù)據(jù)函數(shù)
- 為了防止用戶頻繁觸發(fā)下拉滑動(dòng)滾動(dòng)條,往往需要添加一個(gè)函數(shù)防抖,在指定的時(shí)間內(nèi),只執(zhí)行最后一次事件處理函數(shù),避免頻繁請求數(shù)據(jù),給服務(wù)器造成壓力
代碼實(shí)現(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是滾動(dòng)條滾動(dòng)時(shí),距離頂部的距離 const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 變量scrollHeight是滾動(dòng)條的總高度 const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; // 變量clientHeight是滾動(dòng)條可視區(qū)域的高度 const clientHeight = document.documentElement.clientHeight || document.body.clientHeight; // 當(dāng)滾動(dòng)條到達(dá)底部,并且距離底部小于10px時(shí),加載數(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)用之間的一個(gè)間隔時(shí)間內(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ù)如下所示,實(shí)現(xiàn)方式也很簡單,就是利用定時(shí)器,在規(guī)定的時(shí)間內(nèi),如果再次觸發(fā),則清除定時(shí)器,重新開始計(jì)時(shí)。
只執(zhí)行最后一次
// 函數(shù)的防抖 function debounce(method, duration) { var timer = null; return function(){ var that = this, args = arguments; // 在本次調(diào)用之間的一個(gè)間隔時(shí)間內(nèi)若有方法在執(zhí)行,則終止該方法的執(zhí)行 if(timer) { clearTimeout(timer); } // 開始執(zhí)行本次調(diào)用 timer = setTimeout(function(){ method.apply(that,args); }, duration) } }
至于怎么樣判斷數(shù)據(jù)是否加載完畢,到最后一頁
每次在請求完成數(shù)據(jù)的時(shí)候去判斷一下當(dāng)前的 page × pagesize
是否已經(jīng)大于等于接口返回的total
值就行了,也可以是pageNum
等于total
的時(shí)候,就說明已經(jīng)沒有數(shù)據(jù)了,可以提示用戶了
if(page.value*pagesize.value >= data.length) { alert("沒有更多數(shù)據(jù)了") }
總結(jié)
其實(shí)這個(gè)功能很簡單,但是寫起來還是有點(diǎn)麻煩,因?yàn)樯婕暗疆惒秸埱螅孕枰袛鄶?shù)據(jù)是否加載完畢,還要判斷是否最后一頁,還要判斷是否還有數(shù)據(jù),還要判斷是否需要提示用戶沒有更多數(shù)據(jù)了,所以代碼量還是挺多的,但是寫完之后,感覺還是挺有成就感的。
什么上拉,下拉刷新,下拉加載更多,其實(shí)原理都差不多,都是利用了防抖函數(shù),然后利用定時(shí)器,在規(guī)定的時(shí)間內(nèi),如果再次觸發(fā),則清除定時(shí)器,重新開始計(jì)時(shí)。 實(shí)現(xiàn)方式都差不多
以上就是vuejs實(shí)現(xiàn)滑動(dòng)滾動(dòng)條來加載數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于vuejs滾動(dòng)條加載數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue 全家桶實(shí)現(xiàn)移動(dòng)端酷狗音樂功能
這篇文章主要介紹了Vue 全家桶實(shí)現(xiàn)移動(dòng)端酷狗音樂功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11Vue.js 實(shí)現(xiàn)微信公眾號(hào)菜單編輯器功能(二)
這篇文章主要介紹了Vue.js 實(shí)現(xiàn)微信公眾號(hào)菜單編輯器功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-05-05Vue源碼學(xué)習(xí)之初始化模塊init.js解析
本篇文章主要介紹了Vue源碼學(xué)習(xí)之初始化模塊init.js解析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11vue中的v-model原理,與組件自定義v-model詳解
這篇文章主要介紹了vue中的v-model原理,與組件自定義v-model詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08vue3-vue-router創(chuàng)建靜態(tài)路由和動(dòng)態(tài)路由方式
這篇文章主要介紹了vue3-vue-router創(chuàng)建靜態(tài)路由和動(dòng)態(tài)路由方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10