vue-lazyload核心类详解:LazyContainer与LazyImage实现

vue-lazyload核心类详解:LazyContainer与LazyImage实现

【免费下载链接】vue-lazyload A Vue.js plugin for lazyload your Image or Component in your application. 【免费下载链接】vue-lazyload 项目地址: https://gitcode.com/gh_mirrors/vu/vue-lazyload

一、核心类概述

vue-lazyload作为Vue.js的图片懒加载插件,其核心功能由多个类协同实现。其中src/lazy-container.jssrc/lazy-image.js是实现懒加载的关键组件,它们分别负责容器级懒加载和图片懒加载的具体逻辑。

1.1 类关系图

mermaid

二、LazyContainer容器懒加载实现

2.1 类定义与初始化

LazyContainer类在src/lazy-container.js中定义,主要用于处理容器内图片的批量懒加载。其构造函数接收el、binding、vnode和lazy实例等参数,并初始化队列和配置选项。

class LazyContainer {
  constructor ({ el, binding, vnode, lazy }) {
    this.el = null
    this.vnode = vnode
    this.binding = binding
    this.options = {}
    this.lazy = lazy
    this._queue = []
    this.update({ el, binding })
  }
}

2.2 核心方法解析

2.2.1 update方法

update方法是LazyContainer的核心,它会根据配置选项选择器获取容器内所有图片元素,并为每个图片元素调用lazy.add方法进行懒加载注册。

update ({ el, binding }) {
  this.el = el
  this.options = assign({}, defaultOptions, binding.value)
  const imgs = this.getImgs()
  imgs.forEach(el => {
    this.lazy.add(el, assign({}, this.binding, {
      value: {
        src: 'dataset' in el ? el.dataset.src : el.getAttribute('data-src'),
        error: ('dataset' in el ? el.dataset.error : el.getAttribute('data-error')) || this.options.error,
        loading: ('dataset' in el ? el.dataset.loading : el.getAttribute('data-loading')) || this.options.loading
      }
    }), this.vnode)
  })
}
2.2.2 getImgs方法

getImgs方法通过querySelectorAll获取容器内符合选择器的图片元素,默认选择器为'img'。

getImgs () {
  return ArrayFrom(this.el.querySelectorAll(this.options.selector))
}
2.2.3 clear方法

clear方法用于清除容器内所有图片的懒加载监听,在组件销毁时调用。

clear () {
  const imgs = this.getImgs()
  imgs.forEach(el => this.lazy.remove(el))
  this.vnode = null
  this.binding = null
  this.lazy = null
}

三、LazyImage图片懒加载实现

3.1 组件定义与状态管理

LazyImage在src/lazy-image.js中定义为一个Vue组件,用于单个图片的懒加载处理。它通过data函数维护了图片的加载状态、尺寸信息和渲染地址等。

data () {
  return {
    el: null,
    options: {
      src: '',
      error: '',
      loading: '',
      attempt: lazyManager.options.attempt
    },
    state: {
      loaded: false,
      error: false,
      attempt: 0
    },
    rect: {},
    renderSrc: ''
  }
}

3.2 生命周期与懒加载触发

3.2.1 初始化与挂载

在created钩子中初始化图片配置,mounted钩子中获取DOM元素并注册到懒加载管理器。

created () {
  this.init()
  this.renderSrc = this.options.loading
},
mounted () {
  this.el = this.$el
  lazyManager.addLazyBox(this)
  lazyManager.lazyLoadHandler()
}
3.2.2 视图检查与加载

checkInView方法通过getBoundingClientRect检查图片是否进入视口,load方法负责图片加载逻辑,包含重试机制。

checkInView () {
  this.getRect()
  return inBrowser &&
              (this.rect.top < window.innerHeight * lazyManager.options.preLoad && this.rect.bottom > 0) &&
              (this.rect.left < window.innerWidth * lazyManager.options.preLoad && this.rect.right > 0)
},
load (onFinish = noop) {
  if ((this.state.attempt > this.options.attempt - 1) && this.state.error) {
    if (!lazyManager.options.silent) console.log(`VueLazyload log: ${this.options.src} tried too more than ${this.options.attempt} times`)
    onFinish()
    return
  }
  const src = this.options.src
  loadImageAsync({ src }, ({ src }) => {
    this.renderSrc = src
    this.state.loaded = true
  }, e => {
    this.state.attempt++
    this.renderSrc = this.options.error
    this.state.error = true
  })
}

四、关键工具函数支持

LazyContainer和LazyImage的实现依赖于src/util.js中的多个工具函数,例如:

  • loadImageAsync: 异步加载图片,处理加载成功和失败的回调
  • inBrowser: 检测是否在浏览器环境
  • throttle: 节流函数,优化滚动事件性能
  • getBestSelectionFromSrcset: 根据容器宽度和设备像素比选择合适的图片源

五、与Lazy核心类的协作

LazyContainer和LazyImage都依赖于src/lazy.js中定义的Lazy类进行统一管理。Lazy类维护了一个ListenerQueue队列,负责监听元素是否进入视口,并触发相应的加载逻辑。

// Lazy类核心方法
_lazyLoadHandler () {
  const freeList = []
  this.ListenerQueue.forEach((listener, index) => {
    if (!listener.el || !listener.el.parentNode) {
      freeList.push(listener)
    }
    const catIn = listener.checkInView()
    if (!catIn) return
    listener.load()
  })
  freeList.forEach(item => {
    remove(this.ListenerQueue, item)
    item.$destroy()
  })
}

六、使用场景与最佳实践

6.1 LazyContainer适用场景

  • 长列表图片懒加载,如商品列表
  • 动态生成的图片容器
  • 需要自定义选择器的图片集合

6.2 LazyImage适用场景

  • 单个图片懒加载
  • 需要精细控制加载状态的图片
  • 包含加载中、错误状态显示的图片

七、总结与展望

LazyContainer和LazyImage作为vue-lazyload的核心组件,分别解决了容器级和单图片级的懒加载问题。通过与Lazy类的协作,实现了高效的图片懒加载机制。未来可以考虑进一步优化以下方面:

  1. 增加对视频等其他媒体类型的懒加载支持
  2. 优化交叉观察器(IntersectionObserver)的使用,提高性能
  3. 增加更多的加载状态回调,提供更灵活的定制能力

完整的源码实现可参考项目中的src/lazy-container.jssrc/lazy-image.js文件。

【免费下载链接】vue-lazyload A Vue.js plugin for lazyload your Image or Component in your application. 【免费下载链接】vue-lazyload 项目地址: https://gitcode.com/gh_mirrors/vu/vue-lazyload

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值