Vue實現懶加載的基本思路


懶加載是前端開發者的基本功之一。實現懶加載肯定是要直接操作DOM的,這個沒得跑,但我們可以想辦法讓流程盡可能優雅些。

基本結構

父組件是列表容器,子組件是列表中的項,如卡片、帖子等,承載圖片的DOM對象由子組件直接管理。

<div class="list-container">
    <item v-for="post in postlist" :key="post.id" :images="post.images" :text="post.text"></item>
</div>

實現思路

准備工作

首先,我們需要一個父子組件都能訪問和操作的數組imageList,可以考慮放在一個專門的模塊里,父子組件各自import。

然后,我們定義一個名叫LazyImage的類,用於把圖片的url和DOM綁定在一個對象里,方便操作:

class LazyImage {
    constructor(src) {
        this.src = src;           // 圖片url或base64 this.dom = null;          // 承載圖片的DOM元素 this.status = 'pending';  // 圖片當前狀態
    }
}

其中status表示圖片資源當前的狀態,有pending(未加載)、loading(加載中)、loaded(加載完成或失敗)三個取值。

最后,我們需要一張占位圖,用於圖片加載完成前占位展示。

步驟1

當網頁從服務器拉取到10條帖子時,每個帖子子組件各自把自己負責的圖片和DOM對應起來,放進同一個LazyImage對象,然后push進imageList

這一步有兩個地方需要注意:

1. 承載圖片的DOM對象,其src/background-image值應設為占位圖,真正的圖片url先保存在data-src屬性里,用於圖片url和DOM元素“相認”;

2. 在mounted鈎子函數里直接訪問this.$refs可能為空,因為此時真正的DOM渲染還沒完成,可以放在this.$nextTick的回調函數里訪問。

步驟2

在父組件里監聽window的scroll事件,每次觸發時,先把狀態不為pending的圖片給filter出去,然后檢查一下imageList里的每個圖片的DOM是否在當前可視范圍內里,若是,則將其src/background-image替換為真正的圖片url,不不不,直接替換鏈接不夠優雅,若是原圖很大,網速又不太快,圖片就會像擠牙膏一樣,一點一點地顯露出來,令人捉急。我們可以先new一個Image對象,預加載原圖,待圖片加載完成后,再把真正的url替換上去,做到無縫切換。

注意點:

1. scroll事件觸發頻繁,為減輕對性能的影響,可以加上節流措施,比如設定滾動距離大於一定閾值時才觸發對imageList的遍歷檢查;

2. 在首屏加載完成后,需要手動觸發一次檢查,否則在不滾動的情況下首屏圖片不加載。

 

這樣就輕松實現了圖片的懶加載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM