十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
這篇文章給大家分享的是有關如何實現(xiàn)一個vue無限加載指令的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
vue 中的自定義指令是對底層 dom 進行操作,下面以實現(xiàn)滾動到底部加載數(shù)據(jù),實現(xiàn)無限加載來介紹如何自定義一個簡單的指令。
無限加載的原理是通過對滾動事件的監(jiān)聽,每一次滾動都要獲取到已滾動的距離,如果滾動的距離加上瀏覽器窗口高度,會大于等于內容高度,就觸發(fā)函數(shù)加載數(shù)據(jù)。
先介紹不使用 vue 的情況如何實現(xiàn)無限加載。
不使用框架
首先是html:
實現(xiàn)滾動加載
- 1、hello world
- 2、hello world
- 3、hello world
- 4、hello world
- 5、hello world
- 6、hello world
- 7、hello world
- 8、hello world
- 9、hello world
- 10、hello world
打開瀏覽器,調整下瀏覽器窗口高度,讓頁面可以滾動。
先了解三個變量
document.body.scrollTop 滾動條滾動的距離
window.innerHeight 瀏覽器窗口高度
document.body.clientHeight 內容高度
對應上面的原理就是
window.addEventListener('scroll', function() { var scrollTop = document.body.scrollTop; if(scrollTop + window.innerHeight >= document.body.clientHeight) { // 觸發(fā)加載數(shù)據(jù) loadMore(); } }); function loadMore() { console.log('加載數(shù)據(jù)')' }
loadMore() 函數(shù)就是從接口獲取到數(shù)據(jù),組裝 html,插入到原先到節(jié)點后面。
// 表示列表的序號 var index = 10; function loadMore() { var content = ''; for(var i=0; i< 10; i++) { content += '
這樣就實現(xiàn)了無限加載。
在 vue 中使用指令實現(xiàn)
為什么要用指令實現(xiàn)呢?好像只有指令是可以獲取到底層 dom 的?而實現(xiàn)無限加載,是需要拿到內容高度的。
首先初始化一個項目,添加一個組件,用來顯示列表。
// components/Index.vue
- {{index}}-{{news.title}}
OK,現(xiàn)在開始編寫指令。從傳統(tǒng)實現(xiàn)中,我們了解到要注冊對滾動事件對監(jiān)聽,同時拿到內容高度。
directives: { scroll: { bind: function (el, binding){ window.addEventListener('scroll', ()=> { if(document.body.scrollTop + window.innerHeight >= el.clientHeight) { console.log('load data'); } }) } } }
首先是在組件內注冊了 scroll 指令,然后在指令第一次綁定到組件時,也就是對應著 bind鉤子,注冊滾動監(jiān)聽。
鉤子函數(shù)就是一些生命周期改變時會調用的函數(shù)。bind 在第一次綁定到組件時調用、unbind 在指令與組件解綁時調用。
還可以注意到 bind 對應到函數(shù)有兩個參數(shù),el 和 binding,這是鉤子函數(shù)參數(shù),比如 el 對應綁定的節(jié)點,binding 有很多數(shù)據(jù),比如傳給指令的參數(shù)等。
下面的el.clientHeight就是表示獲取綁定指令的這個節(jié)點的內容高度。
和之前一樣,判斷滾動的高度加上窗口高度是否大于內容高度。
綁定指令到節(jié)點上:
- {{index}}-{{news.title}}
可以看到給指令傳了一個值,這個值就是加載數(shù)據(jù)的函數(shù):
methods: { loadMore() { let newAry = []; for(let i = 0; i < 10; i++) { newAry.push({title: 'hello world'}) } this.newslist = [...this.newslist, ...newAry]; } }
當然,現(xiàn)在在滾動到底部時,只會打印load data,只要把這里改成調用函數(shù)就OK了:
window.addEventListener('scroll', ()=> { if(document.body.scrollTop + window.innerHeight >= el.clientHeight) { let fnc = binding.value; fnc(); } })
v-scroll="loadMore"的 loadMore可以在鉤子函數(shù)參數(shù)的 binding 上拿到。
至此,一個簡單的指令就完成了。
優(yōu)化
上面的例子并沒有真正從接口獲取數(shù)據(jù),所以存在一個隱藏的 bug:當接口響應很慢的情況,滾動到底部正在加載數(shù)據(jù)時,稍微滾動一下仍會觸發(fā)獲取數(shù)據(jù)函數(shù),這會造成同時請求多次接口,一次性返回大量數(shù)據(jù)。
解決辦法是添加一個全局變量 scrollDisable,當?shù)谝淮斡|發(fā)加載數(shù)據(jù)函數(shù)時,將該值設置為 true,根據(jù)該值判斷是否要執(zhí)行加載函數(shù)。
以普通實現(xiàn)為例:
var scrollDisable = false; window.addEventListener('scroll', function() { var scrollTop = document.body.scrollTop; if(scrollTop + window.innerHeight >= document.body.clientHeight) { // 觸發(fā)加載數(shù)據(jù) if(!scrollDisable) { // loadMore(); } } }); // 表示列表的序號 var index = 10; function loadMore() { // 開始加載數(shù)據(jù),就不能再次觸發(fā)這個函數(shù)了 scrollDisable = true; var content = ''; for(var i=0; i< 10; i++) { content += '
感謝各位的閱讀!關于“如何實現(xiàn)一個vue無限加載指令”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。