vant4.0 正式发布了,分析其源码学会用 vue3 写一个图片懒加载组件!

本文通过分析 vant4 的 lazyload 源码,介绍了图片懒加载的原理,包括事件模式和 IntersectionObserver API。通过调试组件,详细讲解了 lazy-image 组件的生命周期、checkInView 和 load 函数。最后,概述了 lazy 类的构造函数和关键方法。学习本文,读者将掌握如何在 Vue3 中开发图片懒加载组件。
摘要由CSDN通过智能技术生成

2022年11月29日首发于掘金,现在同步到公众号。

11. 前言

大家好,我是若川。我倾力持续组织了一年多源码共读,感兴趣的可以加我微信 lxchuan12 参与。另外,想学源码,极力推荐关注我写的专栏《学习源码整体架构系列》,目前是掘金关注人数(4.6k+人)第一的专栏,写有20余篇源码文章。


我们开发业务时经常会使用到组件库,一般来说,很多时候我们不需要关心内部实现。但是如果希望学习和深究里面的原理,这时我们可以分析自己使用的组件库实现。有哪些优雅实现、最佳实践、前沿技术等都可以值得我们借鉴。

相比于原生 JS 等源码。我们或许更应该学习,正在使用的组件库的源码,因为有助于帮助我们写业务和写自己的组件。

如果是 Vue 技术栈,开发移动端的项目,大多会选用 vant 组件库,目前(2022-11-29) star 多达 20.5k,已经正式发布 4.0 了[1]。我们可以挑选 vant 组件库学习,我会写一个组件库源码系列专栏[2],欢迎大家关注。

这次我们来学习 Lazyload 懒加载组件,可以点此查看 `lazyload` 文档体验[4]

学完本文,你将学到:

1. 学会如何用 vue3 + ts 开发一个 lazyload 组件
2. 学会 `lazyload` 图片懒加载组件其原理
3. 学会使用事件和 IntersectionObserver API 实现懒加载
4. 等等

22. 准备工作

看一个开源项目,第一步应该是先看 README.md[5] 再看贡献文档 github/CONTRIBUTING.md[6]

2.1 克隆源码 && 跑起来

You will need Node.js >= 14[7] and pnpm[8].

# 推荐克隆我的项目
git clone https://github.com/lxchuan12/vant-analysis
cd vant-analysis/vant

# 或者克隆官方仓库
git clone git@github.com:vant-ui/vant.git
cd vant

# 安装依赖,如果没安装 pnpm,可以用 npm i pnpm -g 安装,或者查看官网通过其他方式安装
pnpm i

# 启动服务
pnpm dev

执行 pnpm dev 后,这时我们打开懒加载组件 http://localhost:5173/#/zh-CN/lazyload

33. 图片懒加载原理

众所周知,图片懒加载的原理其实相对简单。就是进入可视区再加载图片。涉及到的知识点主要有:节流、新API、IntersectionObserver[9]

大致流程:

  • 事件模式

1. 初始化在元素(比如是 window,但不一定是 window)添加监听滚动和其他相关事件
2. 使用 Element.getBoundingClientRect API 获取元素的大小及其相对于视口的位置,判断是否进入可视化区
3. 图片设置 src 真实的图片路径
4. 离开销毁监听的事件、和移除绑定事件的元素
  • observer 模式

主要是第二步用 IntersectionObserver[10] API。

那么 vant4 中的 lazyload 怎么做的呢。

带着问题我们直接找到 lazyload demo 文件:vant/packages/vant/src/lazyload/demo/index.vue。为什么是这个文件,我在之前文章跟着 vant4 源码学习如何用 vue3+ts 开发一个 loading 组件,仅88行代码分析了其原理,感兴趣的小伙伴点击查看。这里就不赘述了。

44. 利用 demo 调试源码

// vant/packages/vant/src/lazyload/demo/index.vue
// 代码有省略
<script lang="ts">
import Lazyload from '..';

if (window.app) {
  // 手动修改 demo 为如下,添加 lazyImage 为 true
  window.app.use(Lazyload, { lazyComponent: true, lazyImage: true });
}
<script setup lang="ts">
// eslint-disable-next-line import/first
import { cdnURL, useTranslate } from '../../../docs/site';

const t = useTranslate({
  'zh-CN': {
    title2: '背景图懒加载',
    title3: '懒加载模块',
  },
});

const imageList = [
  cdnURL('apple-1.jpeg'),
  cdnURL('apple-2.jpeg'),
  cdnURL('apple-3.jpeg'),
  cdnURL('apple-4.jpeg'),
];
</script>
<template>
  <demo-block :title="t('basicUsage')">
    <!-- 手动修改 demo 为 lazy-image -->
    <lazy-image v-for="img in imageList" :key="img" :src="img">
    </lazy-image>
  </demo-block>
</template>

我们可以看出 lazy-load 为入口文件。

这里先附上两张调试截图。动手调试时可以参考学习。

install 函数调试

682c8263318750c4b1f5164bcd90d67a.png
install 函数调试

LazyClass 调试

3dda5a1ba73db7768e66b6eef2084267.png
lazy-class 调试

55. lazy-load 入口文件

vue-lazyload 文件引入导出和默认导出 Lazyload。 主要包含:

  • 把 lazy 实例对象添加到全局上

  • 注册懒加载组件

  • 注册图片组件

  • 注册指令 lazy

  • 注册指令 lazy-container

// vant/packages/vant/src/lazyload/index.ts
import { Lazyload } from './vue-lazyload';

export default Lazyload;
export { Lazyload };

我们接着来看 vue-lazyload/index.js 主文件。

66. vue-lazyload/index.js 主文件

主要导出一个包含 install 方法的对象 Lazyload

// vant/packages/vant/src/lazyload/vue-lazyload/index.j
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值