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绑定在一个对象里,方便操做:dom

class LazyImage {
    constructor(src) {
        this.src = src;           // 图片url或base64 this.dom = null;          // 承载图片的DOM元素 this.status = 'pending';  // 图片当前状态
    }
}

其中status表示图片资源当前的状态,有pending(未加载)、loading(加载中)、loaded(加载完成或失败)三个取值。函数

最后,咱们须要一张占位图,用于图片加载完成前占位展现。post

步骤1

当网页从服务器拉取到10条帖子时,每一个帖子子组件各自把本身负责的图片和DOM对应起来,放进同一个LazyImage对象,而后push进imageList性能

这一步有两个地方须要注意:this

1. 承载图片的DOM对象,其src/background-image值应设为占位图,真正的图片url先保存在data-src属性里,用于图片url和DOM元素“相认”;url

2. 在mounted钩子函数里直接访问this.$refs可能为空,由于此时真正的DOM渲染还没完成,能够放在this.$nextTick的回调函数里访问。spa

步骤2

在父组件里监听window的scroll事件,每次触发时,先把状态不为pending的图片给filter出去,而后检查一下imageList里的每一个图片的DOM是否在当前可视范围内里,如果,则将其src/background-image替换为真正的图片url,不不不,直接替换连接不够优雅,如果原图很大,网速又不太快,图片就会像挤牙膏同样,一点一点地显露出来,使人捉急。咱们能够先new一个Image对象,预加载原图,待图片加载完成后,再把真正的url替换上去,作到无缝切换。

注意点:

1. scroll事件触发频繁,为减轻对性能的影响,能够加上节流措施,好比设定滚动距离大于必定阈值时才触发对imageList的遍历检查;

2. 在首屏加载完成后,须要手动触发一次检查,不然在不滚动的状况下首屏图片不加载。

 

这样就轻松实现了图片的懒加载。

相关文章
相关标签/搜索