vant-list上拉加載onload事件觸發多次問題及解決
vant-list上拉加載onload事件觸發多次
場景
3個tab頁簽切換時,調用不同接口,在某一個tab隻要翻頁到>=2的情況,當它再點擊到另一個tab的時候,另外一個tab就會連續調用兩次查詢接口
(因為它不僅觸發瞭created還觸發瞭onload事件:且順序為:進入created調用查詢接口,在.then之前,異步查詢還未返回的時候,又會去觸發onload事件,在current+=1之後再次進行查詢)
知識點運用:
一、基礎用法
List 組件通過 loading 和 finished 兩個變量控制加載狀態,當組件滾動到底部時,會觸發 load事件並將 loading 設置成 true。
此時可以發起異步操作並更新數據,數據更新完畢後,將 loading 設置成 false 即可。
若數據已全部加載完畢,則直接將 finished 設置成 true 即可。
二、List 的運行機制是什麼?
List 會監聽瀏覽器的滾動事件並計算列表的位置,當列表底部與可視區域的距離小於offset時,List會觸發一次 load 事件。
三、為什麼 List 初始化後會立即觸發 load 事件?
List 初始化後會觸發一次 load事件,用於加載第一屏的數據,這個特性可以通過immediate-check屬性關閉。
四、為什麼會連續觸發 load 事件?
如果一次請求加載的數據條數較少,導致列表內容無法鋪滿當前屏幕,List 會繼續觸發 load事件,直到內容鋪滿屏幕或數據全部加載完成。
因此你需要調整每次獲取的數據條數,理想情況下每次請求獲取的數據條數應能夠填滿一屏高度。
五、loading 和 finished 分別是什麼含義?
List有以下三種狀態,理解這些狀態有助於你正確地使用List組件:
- 非加載中,loading為false,此時會根據列表滾動位置判斷是否觸發load事件(列表內容不足一屏幕時,會直接觸發)
- 加載中,loading為true,表示正在發送異步請求,此時不會觸發load事件
- 加載完成,finished為true,此時不會觸發load事件 在每次請求完畢後,需要手動將loading設置為false,表示加載結束
這次遇到的問題,可以利用第五點,解決方法:
在進入created的發送請求之前,將this.loading = true , ⇒⇒⇒ (利用:加載中,loading為true,表示正在發送異步請求,此時不會觸發load事件),讓系統知道此時正在異步請求數據,讓它別觸發onload事件
代碼:
<van-list v-model="loading" class="van-list-style" :immediate-check="false" :finished="finished" :finished-text="finishedText" :error.sync="error" error-text="請求失敗,點擊重新加載" @load="onLoad"> <div class="list" v-if="dataList.length > 0"> <div class="list-box2" v-for="(item,index) in dataList" :key="index" @click="handleClick(item)"> ……………………………………… </div> </div> <div v-if="noData" style="margin-top:30%"> <img src="@/common/imgs/no-data.png" alt="" style="width:100%"> </div> </van-list> data() { return { dataList:[], current:1, size:10, loading: false, // 上拉加載 ?????? finished: false, // 上拉加載完畢 error: false, // 是否展示錯誤 finishedText:"沒有更多瞭", noData:false, // 是否展示沒有數據的圖片 // offset: 100 // 滾動條與底部距離小於 offset 時觸發load事件 } }, created() { // 調用列表查詢接口 this.init(this.tab) }, methods:{ init(val) { if(val === '1') { this.createList(1,10) } }, //查詢接口 createList(current,size) { let param = { current:current, size:size } // 重點!!!!!!!!!在這裡將loading置為true ***this.loading = true;*** createList(param).then(res=>{ let that = this if(res.status == true) { //賦值 const dataList = res.body.records const pages = res.body.pages // 如果返回數據為空 if(dataList == null || dataList.length === 0) { that.finished = true that.finishedText = "沒發現任何東西,去其他地方逛逛吧~" that.noData = true return } // 加載狀態結束 可以寫在這裡也可以寫在finally裡面 that.loading = false; // 根據當前頁進行數據處理 if(that.current === 1) { that.dataList = dataList } else { that.dataList = that.dataList.concat(dataList) } // xxx!!!最後一頁不足10條的情況 ,這樣寫實際有問題,因為如果是最後一頁為10條的情況,就會第二次去調用接口 //if(dataList.length < that.size) { // that.finished = true //that.finishedText = '沒有更多瞭'; //} // 使用這種!! 證明已經是最後一頁瞭 if(that.current = pages) { that.finished = true that.finishedText = '沒有更多瞭'; } } }) .catch(err=>{this.error = true; }) .finally(()=>{this.loading = false }) }, // 上拉刷新 onLoad() { this.current+=1 this.createList(this.current,this.size) }, }
總結
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- vant/vue實現小程序下拉刷新功能方法詳解
- vue實現觸底查詢功能
- 微信小程序實現列表分頁功能
- react 實現圖片正在加載中 加載完成 加載失敗三個階段的原理解析
- Python中的內存管理之python list內存使用詳解